)]}'
{"ceilometer/storage/base.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b2784961a2258a84dc829adff3d464ab008bf2ee","unresolved":false,"context_lines":[{"line_number":45,"context_line":"        period_start \u003d next_start"},{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"def _splite_pagination_parameters(model_name, pagination\u003dNone):"},{"line_number":49,"context_line":"    \"\"\"Splite the pagination parameter."},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    :param pagination: class of all parameters used for pagination."}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAARn%2F%2F%2BoA%3D","line":48,"updated":"2013-08-19 12:13:31.000000000","message":"split?","commit_id":"042af70b397cc48be5f530cb535d6bd60b669211"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b2784961a2258a84dc829adff3d464ab008bf2ee","unresolved":false,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"def _splite_pagination_parameters(model_name, pagination\u003dNone):"},{"line_number":49,"context_line":"    \"\"\"Splite the pagination parameter."},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"    :param pagination: class of all parameters used for pagination."},{"line_number":52,"context_line":"    return: limit: maximum number of items to return in one query;"}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAARn%2F%2F%2Bn8%3D","line":49,"updated":"2013-08-19 12:13:31.000000000","message":"Split\n\nparameters","commit_id":"042af70b397cc48be5f530cb535d6bd60b669211"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"b2784961a2258a84dc829adff3d464ab008bf2ee","unresolved":false,"context_lines":[{"line_number":67,"context_line":"        sort_keys, sort_dirs \u003d pagination._get_sort_keys_dirs(model_name)"},{"line_number":68,"context_line":"    if not (sort_keys and sort_dirs):"},{"line_number":69,"context_line":"        sort_keys, sort_dirs \u003d\\"},{"line_number":70,"context_line":"            Pagination._get_default_sort_keys_dirs(model_name)"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    return limit, marker_pair, sort_keys, sort_dirs"},{"line_number":73,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"AAAARn%2F%2F%2Bn0%3D","line":70,"updated":"2013-08-19 12:13:31.000000000","message":"This function should be better placed as a class method on Pagination I guess.","commit_id":"042af70b397cc48be5f530cb535d6bd60b669211"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"e7f3ff56e5985d0f25a1d3f4c35c6be25eeec3eb","unresolved":false,"context_lines":[{"line_number":82,"context_line":"    marker_pairs \u003d {}"},{"line_number":83,"context_line":"    resource_id, meter_name \u003d base64.decodestring(marker_value).split(\u0027+\u0027)"},{"line_number":84,"context_line":"    marker_pairs[\u0027_id\u0027] \u003d resource_id"},{"line_number":85,"context_line":"    marker_pairs[\u0027meter.counter_name\u0027] \u003d meter_name"},{"line_number":86,"context_line":"    return marker_pairs"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2Fvfo%3D","line":85,"updated":"2013-08-30 05:40:19.000000000","message":"Is this naming convention \u0027_id\u0027 and \u0027meter.counter_name\u0027  appropriate for most DB backend or just for mongoDB? \n\nIf it\u0027s only for mongo DB, maybe we should move this into impl_mongodb.py instead, and  only return (resource_id, meter_name) here.","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"4dc423ba368425334a6b5b00ef53acf37db73481","unresolved":false,"context_lines":[{"line_number":82,"context_line":"    marker_pairs \u003d {}"},{"line_number":83,"context_line":"    resource_id, meter_name \u003d base64.decodestring(marker_value).split(\u0027+\u0027)"},{"line_number":84,"context_line":"    marker_pairs[\u0027_id\u0027] \u003d resource_id"},{"line_number":85,"context_line":"    marker_pairs[\u0027meter.counter_name\u0027] \u003d meter_name"},{"line_number":86,"context_line":"    return marker_pairs"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":""}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2Fvas%3D","line":85,"in_reply_to":"AAAASn%2F%2Fvfo%3D","updated":"2013-08-30 06:01:36.000000000","message":"yes, it is only for mongoDB now, it should be moved into impl_mongodb.","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    pass"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"def get_meter_marker_values(marker_value):"},{"line_number":54,"context_line":"    #NOTE(Fengqian): We could not find a primary key for database"},{"line_number":55,"context_line":"    #model of Meter. So, we will use the combination of resource_id"},{"line_number":56,"context_line":"    #and meter_name as a fake key and it needs to parse the marker_value"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fplc%3D","line":53,"updated":"2013-09-01 14:39:33.000000000","message":"This should be part of the Meter model class.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    pass"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"def get_meter_marker_values(marker_value):"},{"line_number":54,"context_line":"    #NOTE(Fengqian): We could not find a primary key for database"},{"line_number":55,"context_line":"    #model of Meter. So, we will use the combination of resource_id"},{"line_number":56,"context_line":"    #and meter_name as a fake key and it needs to parse the marker_value"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fo0s%3D","line":53,"in_reply_to":"AAAASn%2F%2Fplc%3D","updated":"2013-09-02 07:41:58.000000000","message":"Done","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        self.sort_dirs \u003d sort_dirs"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def split_pagination_parameters(model_name, primary_key\u003dNone, pagination\u003dNone):"},{"line_number":88,"context_line":"    \"\"\"Split pagination parameters."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    :param model_name: Name of data collection"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2FplY%3D","line":87,"updated":"2013-09-01 14:39:33.000000000","message":"Why isn\u0027t this a method of the Pagination class?","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        self.sort_dirs \u003d sort_dirs"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def split_pagination_parameters(model_name, primary_key\u003dNone, pagination\u003dNone):"},{"line_number":88,"context_line":"    \"\"\"Split pagination parameters."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    :param model_name: Name of data collection"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fo30%3D","line":87,"in_reply_to":"AAAASn%2F%2FplY%3D","updated":"2013-09-02 07:41:58.000000000","message":"i want this function can provide default values when pagination is None. If put it in Pagination class, i have to add a staticmethod and call it when pagination is None.\nThere is no difference here.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def split_pagination_parameters(model_name, primary_key\u003dNone, pagination\u003dNone):"},{"line_number":88,"context_line":"    \"\"\"Split pagination parameters."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    :param model_name: Name of data collection"},{"line_number":91,"context_line":"    :param primary_key: Primary key of the database."}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fpmo%3D","line":88,"updated":"2013-09-01 14:39:33.000000000","message":"Wow, the return value from this function includes a lot of info. Could you describe it in the docstring here?","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":85,"context_line":""},{"line_number":86,"context_line":""},{"line_number":87,"context_line":"def split_pagination_parameters(model_name, primary_key\u003dNone, pagination\u003dNone):"},{"line_number":88,"context_line":"    \"\"\"Split pagination parameters."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"    :param model_name: Name of data collection"},{"line_number":91,"context_line":"    :param primary_key: Primary key of the database."}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2FopA%3D","line":88,"in_reply_to":"AAAASn%2F%2Fpmo%3D","updated":"2013-09-02 07:41:58.000000000","message":"Done","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    sort_keys, sort_dirs \u003d\\"},{"line_number":97,"context_line":"        ([primary_key], [\u0027desc\u0027]) if primary_key else ([], [])"},{"line_number":98,"context_line":"    #NOTE(Fengqian): Meter has two sort keys here, _id and couneter_name."},{"line_number":99,"context_line":"    if model_name \u003d\u003d \u0027meter\u0027:"},{"line_number":100,"context_line":"        sort_keys, sort_dirs \u003d\\"},{"line_number":101,"context_line":"            (primary_key, [\u0027desc\u0027] * 2) if primary_key else ([], [])"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2FpmY%3D","line":99,"updated":"2013-09-01 14:39:33.000000000","message":"If we have a type-specific default, we should move this logic for getting the default sort keys to the model class and call a method.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"a1c4609bd34c72a6a7370ba5f0b68048624cfaf9","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    sort_keys, sort_dirs \u003d\\"},{"line_number":97,"context_line":"        ([primary_key], [\u0027desc\u0027]) if primary_key else ([], [])"},{"line_number":98,"context_line":"    #NOTE(Fengqian): Meter has two sort keys here, _id and couneter_name."},{"line_number":99,"context_line":"    if model_name \u003d\u003d \u0027meter\u0027:"},{"line_number":100,"context_line":"        sort_keys, sort_dirs \u003d\\"},{"line_number":101,"context_line":"            (primary_key, [\u0027desc\u0027] * 2) if primary_key else ([], [])"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fhuk%3D","line":99,"in_reply_to":"AAAASn%2F%2Fo3k%3D","updated":"2013-09-03 19:45:43.000000000","message":"The models should define the names, and if the drivers need to use different names that can be handled when the query is passed to the driver. We can\u0027t expect users to know which name we gave a column when they are passing us a query, so the API layer needs to be consistent.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":96,"context_line":"    sort_keys, sort_dirs \u003d\\"},{"line_number":97,"context_line":"        ([primary_key], [\u0027desc\u0027]) if primary_key else ([], [])"},{"line_number":98,"context_line":"    #NOTE(Fengqian): Meter has two sort keys here, _id and couneter_name."},{"line_number":99,"context_line":"    if model_name \u003d\u003d \u0027meter\u0027:"},{"line_number":100,"context_line":"        sort_keys, sort_dirs \u003d\\"},{"line_number":101,"context_line":"            (primary_key, [\u0027desc\u0027] * 2) if primary_key else ([], [])"},{"line_number":102,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fo3k%3D","line":99,"in_reply_to":"AAAASn%2F%2FpmY%3D","updated":"2013-09-02 07:41:58.000000000","message":"yes, we can move the default primary key into model class. But here is a problem., for sqlalchemy and MongoDB, the name of the key is different. For example, in Alarm class, mongoDB has \u0027alarm_id\u0027, when sqlalchemy named it \u0027id\u0027. Even if we provide the same key in model class, we still need to do transfer when it comes to each database driver. \n\n\nProviding the sort key in model class absolutely make sense here, so i will do it as the above description, add a transformation on database driver.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":103,"context_line":"    if pagination:"},{"line_number":104,"context_line":"        limit \u003d pagination.limit"},{"line_number":105,"context_line":"        if pagination.marker_value:"},{"line_number":106,"context_line":"            if model_name \u003d\u003d \u0027meter\u0027:"},{"line_number":107,"context_line":"                marker_values \u003d\\"},{"line_number":108,"context_line":"                    get_meter_marker_values(pagination.marker_value)"},{"line_number":109,"context_line":"                marker_pair \u003d dict(zip(primary_key, marker_values))"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2FpmU%3D","line":106,"updated":"2013-09-01 14:39:33.000000000","message":"Same here, this logic should go in the model.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":103,"context_line":"    if pagination:"},{"line_number":104,"context_line":"        limit \u003d pagination.limit"},{"line_number":105,"context_line":"        if pagination.marker_value:"},{"line_number":106,"context_line":"            if model_name \u003d\u003d \u0027meter\u0027:"},{"line_number":107,"context_line":"                marker_values \u003d\\"},{"line_number":108,"context_line":"                    get_meter_marker_values(pagination.marker_value)"},{"line_number":109,"context_line":"                marker_pair \u003d dict(zip(primary_key, marker_values))"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fo0E%3D","line":106,"in_reply_to":"AAAASn%2F%2FpmU%3D","updated":"2013-09-02 07:41:58.000000000","message":"Done","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            sort_dirs[0] \u003d pagination.primary_sort_dir"},{"line_number":119,"context_line":"            #NOTE(Fengqian): Two sort keys of meter have same sort"},{"line_number":120,"context_line":"            #direction."},{"line_number":121,"context_line":"            if model_name \u003d\u003d \u0027meter\u0027:"},{"line_number":122,"context_line":"                sort_dirs[1] \u003d pagination.primary_sort_dir"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    return limit, marker_pair, sort_keys, sort_dirs"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2FpmQ%3D","line":121,"updated":"2013-09-01 14:39:33.000000000","message":"It looks like pagination.primary_sort_dir should be passed to that model method.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            sort_dirs[0] \u003d pagination.primary_sort_dir"},{"line_number":119,"context_line":"            #NOTE(Fengqian): Two sort keys of meter have same sort"},{"line_number":120,"context_line":"            #direction."},{"line_number":121,"context_line":"            if model_name \u003d\u003d \u0027meter\u0027:"},{"line_number":122,"context_line":"                sort_dirs[1] \u003d pagination.primary_sort_dir"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    return limit, marker_pair, sort_keys, sort_dirs"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fo0A%3D","line":121,"in_reply_to":"AAAASn%2F%2FpmQ%3D","updated":"2013-09-02 07:41:58.000000000","message":"Done","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"dd7f6b0246bd375e57ba977ff6ab9f962550ba7c","unresolved":false,"context_lines":[{"line_number":86,"context_line":"    :param sort_keys: Array of attributes by which results be sorted."},{"line_number":87,"context_line":"    return: Updated marker_pairs and sort_keys."},{"line_number":88,"context_line":"    \"\"\""},{"line_number":89,"context_line":"    for new_key, old_key in zip(keys, model_keys):"},{"line_number":90,"context_line":"        if marker_pair:"},{"line_number":91,"context_line":"            marker_pair[new_key] \u003d marker_pair.pop(old_key)"},{"line_number":92,"context_line":"        if sort_keys:"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2FoPc%3D","line":89,"updated":"2013-09-02 08:16:38.000000000","message":"I guess it\u0027s the caller\u0027s responsibility to make sure the old_key exists in marker_pair and sort_keys? Otherwise I see exception in this function. If so, it\u0027d be better to add this requirement into the comment.","commit_id":"cd9e5c62815a497e364bb87286723f83775a9f3a"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"dd7f6b0246bd375e57ba977ff6ab9f962550ba7c","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            marker_pair[new_key] \u003d marker_pair.pop(old_key)"},{"line_number":92,"context_line":"        if sort_keys:"},{"line_number":93,"context_line":"            index \u003d sort_keys.index(old_key)"},{"line_number":94,"context_line":"            del sort_keys[index]"},{"line_number":95,"context_line":"            sort_keys.insert(index, new_key)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    return marker_pair, sort_keys"}],"source_content_type":"text/x-python","patch_set":13,"id":"AAAASn%2F%2FoQo%3D","line":94,"updated":"2013-09-02 08:16:38.000000000","message":"why del here?\nhow about sort_keys[index] \u003d new_key?","commit_id":"cd9e5c62815a497e364bb87286723f83775a9f3a"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"6ab537ff92473ab940385d24e4867669a35c844c","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.sort_dirs \u003d sort_dirs"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"def keys_translate(keys, model_keys, marker_pair, sort_keys):"},{"line_number":76,"context_line":"    #NOTE(Fengqian): Different database have different key name,"},{"line_number":77,"context_line":"    #for example, alarm_id in mongoDB is named id in table Alarm of"},{"line_number":78,"context_line":"    #sqlalchemy. In model class, we provide the same keys and need to"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FggQ%3D","line":75,"updated":"2013-09-03 23:37:47.000000000","message":"This function should be a method of the driver base class. \n\nThe \"model_keys\" argument should be a class attribute of the driver (nested dictionary keyed by model name and then providing the mapping between the \"public\" column name and the private name). The base driver should have an empty mapping, and the subclasses can override it. The method would then return its input values without modification for the base class, and individual drivers only need to provide the column maps.","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        self.sort_dirs \u003d sort_dirs"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"def keys_translate(keys, model_keys, marker_pair, sort_keys):"},{"line_number":76,"context_line":"    #NOTE(Fengqian): Different database have different key name,"},{"line_number":77,"context_line":"    #for example, alarm_id in mongoDB is named id in table Alarm of"},{"line_number":78,"context_line":"    #sqlalchemy. In model class, we provide the same keys and need to"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FfjE%3D","line":75,"in_reply_to":"AAAASn%2F%2FggQ%3D","updated":"2013-09-05 07:18:16.000000000","message":"Done","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"6ab537ff92473ab940385d24e4867669a35c844c","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    return marker_pair, sort_keys"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"def split_pagination_parameters(model_class, pagination\u003dNone):"},{"line_number":103,"context_line":"    \"\"\"Split pagination parameters."},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    :param model_class: class of data base model."}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2Fgjk%3D","line":102,"updated":"2013-09-03 23:37:47.000000000","message":"I still think this belongs in the Pagination class. A class method to provide a default instance of Pagination (configured to not paginate) would let us move all of the pagination argument code into that class.","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":99,"context_line":"    return marker_pair, sort_keys"},{"line_number":100,"context_line":""},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"def split_pagination_parameters(model_class, pagination\u003dNone):"},{"line_number":103,"context_line":"    \"\"\"Split pagination parameters."},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    :param model_class: class of data base model."}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FfjA%3D","line":102,"in_reply_to":"AAAASn%2F%2Fgjk%3D","updated":"2013-09-05 07:18:16.000000000","message":"Done","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"303c0e7d9441db8a2bd295e0bdca688d5989c872","unresolved":false,"context_lines":[{"line_number":298,"context_line":"        #translate in driver end."},{"line_number":299,"context_line":"        \"\"\"Translate the keys of different database."},{"line_number":300,"context_line":""},{"line_number":301,"context_line":"        :param keys: Specific keys of certain database"},{"line_number":302,"context_line":"        :param model_name: Name of model class."},{"line_number":303,"context_line":"        \"\"\""},{"line_number":304,"context_line":"        model_key \u003d cls.TRANSLATE_KEYS[model_name]"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAATH%2F%2FXuU%3D","line":301,"updated":"2013-10-17 03:48:00.000000000","message":"keys must be a list according to the implementation, right? Please put it clearly here.","commit_id":"8c7784c1b8cec689d56ac9ffe6aeb1fa74ed0866"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"303c0e7d9441db8a2bd295e0bdca688d5989c872","unresolved":false,"context_lines":[{"line_number":305,"context_line":"        for key in keys:"},{"line_number":306,"context_line":"            if key in model_key.keys():"},{"line_number":307,"context_line":"                keys[keys.index(key)] \u003d model_key[key]"},{"line_number":308,"context_line":"        return keys"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAATH%2F%2FXtw%3D","line":308,"updated":"2013-10-17 03:48:00.000000000","message":"how about change the above 4 lines to:\n\nreturn map(lambda x: model_key[x] if x in model_key.keys() else x, keys)","commit_id":"8c7784c1b8cec689d56ac9ffe6aeb1fa74ed0866"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"d29034d77b3a8acbdb829005f056b3411f2f97a1","unresolved":false,"context_lines":[{"line_number":303,"context_line":"    @abc.abstractmethod"},{"line_number":304,"context_line":"    def get_events(self, event_filter):"},{"line_number":305,"context_line":"        \"\"\"Return an iterable of model.Event objects."},{"line_number":306,"context_line":"        \"\"\""},{"line_number":307,"context_line":"    @classmethod"},{"line_number":308,"context_line":"    def keys_translate(cls, keys, model_name):"},{"line_number":309,"context_line":"        #NOTE(Fengqian): Different database have different key name,"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAATn%2F99CU%3D","line":306,"updated":"2013-12-04 06:47:28.000000000","message":"I think an empty line is needed here.","commit_id":"7aee1b6f07502183c27bd835046fcc9ff262628d"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"dd870bb2bad7fba8d20624110fa9c287a3f667b4","unresolved":false,"context_lines":[{"line_number":303,"context_line":"    @abc.abstractmethod"},{"line_number":304,"context_line":"    def get_events(self, event_filter):"},{"line_number":305,"context_line":"        \"\"\"Return an iterable of model.Event objects."},{"line_number":306,"context_line":"        \"\"\""},{"line_number":307,"context_line":"    @classmethod"},{"line_number":308,"context_line":"    def keys_translate(cls, keys, model_name):"},{"line_number":309,"context_line":"        #NOTE(Fengqian): Different database have different key name,"}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAATn%2F93ZY%3D","line":306,"in_reply_to":"AAAATn%2F99CU%3D","updated":"2013-12-05 05:32:13.000000000","message":"Done","commit_id":"7aee1b6f07502183c27bd835046fcc9ff262628d"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        period_start \u003d next_start"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def split_combinate_marker_values(marker_value):"},{"line_number":52,"context_line":"    \"\"\"Split the combinated maker values with base64 encodeing."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    :param marker_value: The conbination of marker values with base64 encoding."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhgk%3D","line":51,"updated":"2014-01-12 20:57:10.000000000","message":"Here and in the docstring... \"combinate\" is not an English word. I suggest you use \"combined\" here.","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":48,"context_line":"        period_start \u003d next_start"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"def split_combinate_marker_values(marker_value):"},{"line_number":52,"context_line":"    \"\"\"Split the combinated maker values with base64 encodeing."},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    :param marker_value: The conbination of marker values with base64 encoding."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FZqQ%3D","line":51,"in_reply_to":"AAAAUH%2F%2Fhgk%3D","updated":"2014-01-17 06:55:51.000000000","message":"Done","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    \"\"\""},{"line_number":58,"context_line":"    decode_str \u003d base64.decodestring(marker_value)"},{"line_number":59,"context_line":"    if \u0027+\u0027 not in decode_str:"},{"line_number":60,"context_line":"        raise ValueError(\"Invalid input of marker_value\")"},{"line_number":61,"context_line":"    return decode_str.split(\u0027+\u0027)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhgg%3D","line":60,"updated":"2014-01-12 20:57:10.000000000","message":"Why do we care here if + is not in the string? If it isn\u0027t, then the split(\u0027+\u0027) below will only yield a single-element list, which is fine, no?","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":57,"context_line":"    \"\"\""},{"line_number":58,"context_line":"    decode_str \u003d base64.decodestring(marker_value)"},{"line_number":59,"context_line":"    if \u0027+\u0027 not in decode_str:"},{"line_number":60,"context_line":"        raise ValueError(\"Invalid input of marker_value\")"},{"line_number":61,"context_line":"    return decode_str.split(\u0027+\u0027)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FZqM%3D","line":60,"in_reply_to":"AAAAUH%2F%2Fhgg%3D","updated":"2014-01-17 06:55:51.000000000","message":"Done","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":347,"context_line":"        raise NotImplementedError(_(\u0027Events not implemented.\u0027))"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"    @classmethod"},{"line_number":350,"context_line":"    def keys_translate(cls, keys, model_name):"},{"line_number":351,"context_line":"        #NOTE(Fengqian): Different database have different key name,"},{"line_number":352,"context_line":"        #for example, alarm_id in mongoDB is named id in table Alarm of"},{"line_number":353,"context_line":"        #sqlalchemy. In model class, we provide the same keys and need to"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhdk%3D","line":350,"updated":"2014-01-12 20:57:10.000000000","message":"Would you mind changing this to \"translate_keys\" instead of \"keys_translate\"? All of the other methods have the verb before the noun...","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":347,"context_line":"        raise NotImplementedError(_(\u0027Events not implemented.\u0027))"},{"line_number":348,"context_line":""},{"line_number":349,"context_line":"    @classmethod"},{"line_number":350,"context_line":"    def keys_translate(cls, keys, model_name):"},{"line_number":351,"context_line":"        #NOTE(Fengqian): Different database have different key name,"},{"line_number":352,"context_line":"        #for example, alarm_id in mongoDB is named id in table Alarm of"},{"line_number":353,"context_line":"        #sqlalchemy. In model class, we provide the same keys and need to"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FZpo%3D","line":350,"in_reply_to":"AAAAUH%2F%2Fhdk%3D","updated":"2014-01-17 06:55:51.000000000","message":"Done","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        :param model_class: class of data base model."},{"line_number":92,"context_line":"        return: parameters used for pagination query."},{"line_number":93,"context_line":"                limit: Maximum number of items to return."},{"line_number":94,"context_line":"                marker_value: Value/vlaues to identify the last item of"},{"line_number":95,"context_line":"                             the previous page."},{"line_number":96,"context_line":"                sort_keys: Array of attributes by which results be sorted."},{"line_number":97,"context_line":"                sort_dirs: Per-column array of sort_dirs, corresponding to"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFzM%3D","line":94,"updated":"2014-01-17 15:27:09.000000000","message":"s/Value\\/vlaues/Value(s)/","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3565ea1572c73f828e03c4ba859c4a015d487bad","unresolved":false,"context_lines":[{"line_number":91,"context_line":"        :param model_class: class of data base model."},{"line_number":92,"context_line":"        return: parameters used for pagination query."},{"line_number":93,"context_line":"                limit: Maximum number of items to return."},{"line_number":94,"context_line":"                marker_value: Value/vlaues to identify the last item of"},{"line_number":95,"context_line":"                             the previous page."},{"line_number":96,"context_line":"                sort_keys: Array of attributes by which results be sorted."},{"line_number":97,"context_line":"                sort_dirs: Per-column array of sort_dirs, corresponding to"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2B%2FPw%3D","line":94,"in_reply_to":"AAAAUH%2F%2FFzM%3D","updated":"2014-02-10 03:25:35.000000000","message":"Done","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            #To ensure at least one unique column is in the sort keys,"},{"line_number":110,"context_line":"            #We add the primary key at the end of keys list from user."},{"line_number":111,"context_line":"            sort_dirs \u003d self.sort_dirs + sort_dirs"},{"line_number":112,"context_line":"            sort_keys \u003d self.sort_keys + sort_keys"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"        return self.limit, self.marker_value, sort_keys, sort_dirs"},{"line_number":115,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFyQ%3D","line":112,"updated":"2014-01-17 15:27:09.000000000","message":"++. Excellent.","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"}],"ceilometer/storage/impl_db2.py":[{"author":{"_account_id":5313,"name":"David Peraza","email":"david_peraza@persistentsys.com","username":"dperaza"},"change_message_id":"5e381c98b0001a06038c8bf2c2d0ec2626b4de70","unresolved":false,"context_lines":[{"line_number":37,"context_line":"from ceilometer.openstack.common import timeutils"},{"line_number":38,"context_line":"from ceilometer import storage"},{"line_number":39,"context_line":"from ceilometer.storage import base"},{"line_number":40,"context_line":"from ceilometer.storage.base import Pagination"},{"line_number":41,"context_line":"from ceilometer.storage import models"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"LOG \u003d log.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2F5fY%3D","line":40,"updated":"2013-10-25 14:57:52.000000000","message":"Do we allow import of classes?","commit_id":"b1a229560d044e442aa060a0eb815f51732ba740"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"fa3da90f2d3c0e325abb991d54d11b97f81da7b7","unresolved":false,"context_lines":[{"line_number":37,"context_line":"from ceilometer.openstack.common import timeutils"},{"line_number":38,"context_line":"from ceilometer import storage"},{"line_number":39,"context_line":"from ceilometer.storage import base"},{"line_number":40,"context_line":"from ceilometer.storage.base import Pagination"},{"line_number":41,"context_line":"from ceilometer.storage import models"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"LOG \u003d log.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2FyNY%3D","line":40,"in_reply_to":"AAAATn%2F%2F5fY%3D","updated":"2013-10-29 07:50:07.000000000","message":"Done","commit_id":"b1a229560d044e442aa060a0eb815f51732ba740"},{"author":{"_account_id":5313,"name":"David Peraza","email":"david_peraza@persistentsys.com","username":"dperaza"},"change_message_id":"5e381c98b0001a06038c8bf2c2d0ec2626b4de70","unresolved":false,"context_lines":[{"line_number":234,"context_line":"        :return: sort parameters"},{"line_number":235,"context_line":"        \"\"\""},{"line_number":236,"context_line":"        sort_instructions \u003d []"},{"line_number":237,"context_line":"        for sort_key, sort_dir in zip(sort_keys, sort_dirs):"},{"line_number":238,"context_line":"            _sort_dir \u003d cls.SORT_OPERATION_MAP.get("},{"line_number":239,"context_line":"                sort_dir, cls.SORT_OPERATION_MAP[\u0027desc\u0027])"},{"line_number":240,"context_line":"            _instruction \u003d (sort_key, _sort_dir)"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2F5hQ%3D","line":237,"updated":"2013-10-25 14:57:52.000000000","message":"instead of doing this, why not just pass a dictionary, that way there is not risk on sort_dirs being shorter that sort_keys. If you must use zip I recommend using http://docs.python.org/2/library/itertools.html#itertools.izip so that there is not extra copies.","commit_id":"b1a229560d044e442aa060a0eb815f51732ba740"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"fa3da90f2d3c0e325abb991d54d11b97f81da7b7","unresolved":false,"context_lines":[{"line_number":234,"context_line":"        :return: sort parameters"},{"line_number":235,"context_line":"        \"\"\""},{"line_number":236,"context_line":"        sort_instructions \u003d []"},{"line_number":237,"context_line":"        for sort_key, sort_dir in zip(sort_keys, sort_dirs):"},{"line_number":238,"context_line":"            _sort_dir \u003d cls.SORT_OPERATION_MAP.get("},{"line_number":239,"context_line":"                sort_dir, cls.SORT_OPERATION_MAP[\u0027desc\u0027])"},{"line_number":240,"context_line":"            _instruction \u003d (sort_key, _sort_dir)"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2FyLk%3D","line":237,"in_reply_to":"AAAATn%2F%2F5hQ%3D","updated":"2013-10-29 07:50:07.000000000","message":"I will use izip here. And i think we do not need to check if the sort key and sort dirs has equal length. I will add the check in API level, anyway, we only need to guarantee the sort keys and sort dirs from users have same length.","commit_id":"b1a229560d044e442aa060a0eb815f51732ba740"},{"author":{"_account_id":5313,"name":"David Peraza","email":"david_peraza@persistentsys.com","username":"dperaza"},"change_message_id":"5e381c98b0001a06038c8bf2c2d0ec2626b4de70","unresolved":false,"context_lines":[{"line_number":429,"context_line":""},{"line_number":430,"context_line":"        #NOTE(fengqian): Keep in line with the previous sort keys/directions"},{"line_number":431,"context_line":"        sort_keys, sort_dirs \u003d Pagination.get_sort_from_model(models.Resource)"},{"line_number":432,"context_line":"        sort_keys +\u003d [\u0027timestamp\u0027, \u0027user_id\u0027, \u0027project_id\u0027]"},{"line_number":433,"context_line":"        sort_dirs +\u003d [\u0027desc\u0027] * 3"},{"line_number":434,"context_line":""},{"line_number":435,"context_line":"        sort_instructions \u003d self._build_sort_instructions(sort_keys\u003dsort_keys,"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2F5f0%3D","line":432,"updated":"2013-10-25 14:57:52.000000000","message":"just a question, why are these keys not returned by get_sort_from_model call? Does it make a diff if you add in front or after current keys?","commit_id":"b1a229560d044e442aa060a0eb815f51732ba740"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"fa3da90f2d3c0e325abb991d54d11b97f81da7b7","unresolved":false,"context_lines":[{"line_number":429,"context_line":""},{"line_number":430,"context_line":"        #NOTE(fengqian): Keep in line with the previous sort keys/directions"},{"line_number":431,"context_line":"        sort_keys, sort_dirs \u003d Pagination.get_sort_from_model(models.Resource)"},{"line_number":432,"context_line":"        sort_keys +\u003d [\u0027timestamp\u0027, \u0027user_id\u0027, \u0027project_id\u0027]"},{"line_number":433,"context_line":"        sort_dirs +\u003d [\u0027desc\u0027] * 3"},{"line_number":434,"context_line":""},{"line_number":435,"context_line":"        sort_instructions \u003d self._build_sort_instructions(sort_keys\u003dsort_keys,"}],"source_content_type":"text/x-python","patch_set":23,"id":"AAAATn%2F%2Fx4c%3D","line":432,"in_reply_to":"AAAATn%2F%2F5f0%3D","updated":"2013-10-29 07:50:07.000000000","message":"In model class, we only provide primary key with default sort direction. Other sort instruction should from users. But db2 does not support pagination now but only sorting, so i just want to keep in line with the previous sort keys and sort directions.\nAfter db2 pagination added, these lines should removed.\n\nYes, it is different if you  add in front or after current keys.","commit_id":"b1a229560d044e442aa060a0eb815f51732ba740"}],"ceilometer/storage/impl_mongodb.py":[{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"c5828e03c0b3c744a6aad4c094b7723975bfc91f","unresolved":false,"context_lines":[{"line_number":389,"context_line":"        \"\"\"Return the mark document according to the attribute-value pairs."},{"line_number":390,"context_line":""},{"line_number":391,"context_line":"        :param db_collection: Database collection that be query."},{"line_number":392,"context_line":"        :param maker_pair: Attribute-value pair filter to identify a object."},{"line_number":393,"context_line":"                            The marker_pair users passed in should be"},{"line_number":394,"context_line":"                            specific enough to identify only one object."},{"line_number":395,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARH%2F%2F6Kw%3D","line":392,"updated":"2013-08-15 12:11:11.000000000","message":"s/maker/marker/","commit_id":"37a5495572f9b102d91fb16e1ecbd091adb4c8b9"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"c5828e03c0b3c744a6aad4c094b7723975bfc91f","unresolved":false,"context_lines":[{"line_number":401,"context_line":"        if ret.count() \u003d\u003d 0:"},{"line_number":402,"context_line":"            raise base.NoResultFound"},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"        return ret.__getitem__(0)"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    @classmethod"},{"line_number":407,"context_line":"    def _recurse_sort_keys(cls, sort_keys, marker, flag):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARH%2F%2F6Ks%3D","line":404,"updated":"2013-08-15 12:11:11.000000000","message":"getitem(ret, 0)","commit_id":"37a5495572f9b102d91fb16e1ecbd091adb4c8b9"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"2c07e1649cf4478e5cacf5caca819e2f49e66f04","unresolved":false,"context_lines":[{"line_number":401,"context_line":"        if ret.count() \u003d\u003d 0:"},{"line_number":402,"context_line":"            raise base.NoResultFound"},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"        return ret.__getitem__(0)"},{"line_number":405,"context_line":""},{"line_number":406,"context_line":"    @classmethod"},{"line_number":407,"context_line":"    def _recurse_sort_keys(cls, sort_keys, marker, flag):"}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARH%2F%2F6CU%3D","line":404,"in_reply_to":"AAAARH%2F%2F6Ks%3D","updated":"2013-08-15 13:03:44.000000000","message":"getitem(ret, 0), can we use it like this?\n\n\nI will use ret[0] instead:)","commit_id":"37a5495572f9b102d91fb16e1ecbd091adb4c8b9"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"a32e4e191704987a0e22288a3895e42f96b66403","unresolved":false,"context_lines":[{"line_number":513,"context_line":"                      start_timestamp\u003dNone, start_timestamp_op\u003dNone,"},{"line_number":514,"context_line":"                      end_timestamp\u003dNone, end_timestamp_op\u003dNone,"},{"line_number":515,"context_line":"                      metaquery\u003d{}, resource\u003dNone, limit\u003dNone,"},{"line_number":516,"context_line":"                      marker_pair\u003dNone, sort_key\u003dNone, sort_dir\u003dNone):"},{"line_number":517,"context_line":"        \"\"\"Return an iterable of models.Resource instances"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        :param user: Optional ID for user that owns the resource."}],"source_content_type":"text/x-python","patch_set":2,"id":"AAAARH%2F%2F4Rc%3D","line":516,"updated":"2013-08-15 20:19:59.000000000","message":"These changesets are in an odd order. This one adds arguments to a driver, without adding them to the base class for all drivers. See my comments on the other changeset about combining the pagination arguments into a single value to be passed to the driver.","commit_id":"37a5495572f9b102d91fb16e1ecbd091adb4c8b9"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"0f5733eeccd25b1dedcb88fac96aca18ec1449c0","unresolved":false,"context_lines":[{"line_number":542,"context_line":"                            3)\u0027sort_keys\u0027, array of attributes by which results"},{"line_number":543,"context_line":"                            should be sorted;"},{"line_number":544,"context_line":"                            4)\u0027sort_dirs\u0027, per-column array of sort_dirs,"},{"line_number":545,"context_line":"                            corresponding to sort_keys."},{"line_number":546,"context_line":"        \"\"\""},{"line_number":547,"context_line":"        limit, marker_pair, sort_keys, sort_dirs \u003d\\"},{"line_number":548,"context_line":"            pagination.split_pagination_parameters(\u0027resource\u0027) \\"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAASX%2F%2F62w%3D","line":545,"updated":"2013-08-23 18:49:14.000000000","message":"copied from base.py. difficult to manage all these definitions everywhere","commit_id":"ad52eb810e9aff2b6fe14d1172af19a4ec8eb1d1"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"0f5733eeccd25b1dedcb88fac96aca18ec1449c0","unresolved":false,"context_lines":[{"line_number":643,"context_line":"                            3)\u0027sort_keys\u0027, array of attributes by which results"},{"line_number":644,"context_line":"                            should be sorted;"},{"line_number":645,"context_line":"                            4)\u0027sort_dirs\u0027, per-column array of sort_dirs,"},{"line_number":646,"context_line":"                            corresponding to sort_keys."},{"line_number":647,"context_line":"        \"\"\""},{"line_number":648,"context_line":"        q \u003d {}"},{"line_number":649,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAASX%2F%2F61k%3D","line":646,"updated":"2013-08-23 18:49:14.000000000","message":"same as above","commit_id":"ad52eb810e9aff2b6fe14d1172af19a4ec8eb1d1"},{"author":{"_account_id":6537,"name":"gordon chung","email":"gord@live.ca","username":"chungg"},"change_message_id":"0f5733eeccd25b1dedcb88fac96aca18ec1449c0","unresolved":false,"context_lines":[{"line_number":772,"context_line":"                            3)\u0027sort_keys\u0027, array of attributes by which results"},{"line_number":773,"context_line":"                            should be sorted;"},{"line_number":774,"context_line":"                            4)\u0027sort_dirs\u0027, per-column array of sort_dirs,"},{"line_number":775,"context_line":"                            corresponding to sort_keys."},{"line_number":776,"context_line":"        \"\"\""},{"line_number":777,"context_line":"        q \u003d {}"},{"line_number":778,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":6,"id":"AAAASX%2F%2F61M%3D","line":775,"updated":"2013-08-23 18:49:14.000000000","message":"same as above","commit_id":"ad52eb810e9aff2b6fe14d1172af19a4ec8eb1d1"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"e7f3ff56e5985d0f25a1d3f4c35c6be25eeec3eb","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        if marker_pair:"},{"line_number":634,"context_line":"            raise NotImplementedError("},{"line_number":635,"context_line":"                \"Cannot use marker value in resource listing, not implemented\")"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"        q \u003d {}"},{"line_number":638,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2Fvd4%3D","line":635,"updated":"2013-08-30 05:40:19.000000000","message":"Does this raise mean that get_resources() never support pagination? Because marker_pair would always be true if pagination.marker_value is true according to the method split_pagination_parameters()","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"e521c1460c393275c15f5e1f253dffebbd7f48f7","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        if marker_pair:"},{"line_number":634,"context_line":"            raise NotImplementedError("},{"line_number":635,"context_line":"                \"Cannot use marker value in resource listing, not implemented\")"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"        q \u003d {}"},{"line_number":638,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2FuzM%3D","line":635,"in_reply_to":"AAAASn%2F%2Fu48%3D","updated":"2013-08-30 09:33:30.000000000","message":"There\u0027s no way you\u0027ll pass all unit tests with find().","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"59b24c6416a80ed8248ba8d891c79aeb4a9bdcef","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        if marker_pair:"},{"line_number":634,"context_line":"            raise NotImplementedError("},{"line_number":635,"context_line":"                \"Cannot use marker value in resource listing, not implemented\")"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"        q \u003d {}"},{"line_number":638,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2FuyM%3D","line":635,"in_reply_to":"AAAASn%2F%2Fuyg%3D","updated":"2013-08-30 09:38:40.000000000","message":"Yes, that\u0027s what the current code do.","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"4bd682294c4f364d5b22f90e7180a90a84f0493b","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        if marker_pair:"},{"line_number":634,"context_line":"            raise NotImplementedError("},{"line_number":635,"context_line":"                \"Cannot use marker value in resource listing, not implemented\")"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"        q \u003d {}"},{"line_number":638,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2Fuyg%3D","line":635,"in_reply_to":"AAAASn%2F%2FuzM%3D","updated":"2013-08-30 09:36:58.000000000","message":"So, we have to disable pagination for get_resource of mongodb for now, right?","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"70a899a3ef3ef8fd66d92e1bc81b1fd1cdeb2443","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        if marker_pair:"},{"line_number":634,"context_line":"            raise NotImplementedError("},{"line_number":635,"context_line":"                \"Cannot use marker value in resource listing, not implemented\")"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"        q \u003d {}"},{"line_number":638,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2Fu48%3D","line":635,"in_reply_to":"AAAASn%2F%2FvBg%3D","updated":"2013-08-30 09:03:05.000000000","message":"Can we rebase back and using find() then?","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"ba94cedd160222c8bba0c71011264e5f227f77e4","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        if marker_pair:"},{"line_number":634,"context_line":"            raise NotImplementedError("},{"line_number":635,"context_line":"                \"Cannot use marker value in resource listing, not implemented\")"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"        q \u003d {}"},{"line_number":638,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2FvBg%3D","line":635,"in_reply_to":"AAAASn%2F%2FvZ4%3D","updated":"2013-08-30 08:08:45.000000000","message":"It\u0027s impossible to paginate on an aggregation via the current mechanism using find() in this driver.\nThat may be done in pure Python, but this function doesn\u0027t implement it yet.","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"4dc423ba368425334a6b5b00ef53acf37db73481","unresolved":false,"context_lines":[{"line_number":632,"context_line":""},{"line_number":633,"context_line":"        if marker_pair:"},{"line_number":634,"context_line":"            raise NotImplementedError("},{"line_number":635,"context_line":"                \"Cannot use marker value in resource listing, not implemented\")"},{"line_number":636,"context_line":""},{"line_number":637,"context_line":"        q \u003d {}"},{"line_number":638,"context_line":"        if user is not None:"}],"source_content_type":"text/x-python","patch_set":10,"id":"AAAASn%2F%2FvZ4%3D","line":635,"in_reply_to":"AAAASn%2F%2Fvd4%3D","updated":"2013-08-30 06:01:36.000000000","message":"i think so.  This change is made by Julien Danjou.  In the previous patch, it is there already. \n\nYou can see https://review.openstack.org/#/c/42582/8/ceilometer/storage/impl_mongodb.py","commit_id":"0a2df3ee70775aa11eafa16f82774e3658afbdc6"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":647,"context_line":"            }},"},{"line_number":648,"context_line":"        ])"},{"line_number":649,"context_line":""},{"line_number":650,"context_line":"        for result in aggregate[\u0027result\u0027]:"},{"line_number":651,"context_line":"            if limit is not None:"},{"line_number":652,"context_line":"                if limit \u003d\u003d 0:"},{"line_number":653,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2FpmE%3D","line":650,"updated":"2013-09-01 14:39:33.000000000","message":"The slicing can be done in the for loop, and this check and management of the limit variable isn\u0027t needed.\n\n  for result in aggregate[\u0027result\u0027][:limit]:\n\nPassing None to a slice is like taking the whole sequence, so there\u0027s no need to test limit first.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":647,"context_line":"            }},"},{"line_number":648,"context_line":"        ])"},{"line_number":649,"context_line":""},{"line_number":650,"context_line":"        for result in aggregate[\u0027result\u0027]:"},{"line_number":651,"context_line":"            if limit is not None:"},{"line_number":652,"context_line":"                if limit \u003d\u003d 0:"},{"line_number":653,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fo2o%3D","line":650,"in_reply_to":"AAAASn%2F%2FpmE%3D","updated":"2013-09-02 07:41:58.000000000","message":"Done","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"6ab537ff92473ab940385d24e4867669a35c844c","unresolved":false,"context_lines":[{"line_number":431,"context_line":"        self.db.resource.remove({\u0027_id\u0027: {\u0027$nin\u0027: results[\u0027resources\u0027]}})"},{"line_number":432,"context_line":""},{"line_number":433,"context_line":"    @staticmethod"},{"line_number":434,"context_line":"    def _get_marker(db_collection, marker_pair):"},{"line_number":435,"context_line":"        \"\"\"Return the mark document according to the attribute-value pairs."},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"        :param db_collection: Database collection that be query."}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2Fgi8%3D","line":434,"updated":"2013-09-03 23:37:47.000000000","message":"Now that the marker value is something we can search for, this shouldn\u0027t be needed any more.","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"6ab537ff92473ab940385d24e4867669a35c844c","unresolved":false,"context_lines":[{"line_number":450,"context_line":"        return ret[0]"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    @classmethod"},{"line_number":453,"context_line":"    def _recurse_sort_keys(cls, sort_keys, marker, sort_flags):"},{"line_number":454,"context_line":"        _first_key \u003d sort_keys[0]"},{"line_number":455,"context_line":"        _first_flag \u003d sort_flags[0]"},{"line_number":456,"context_line":"        value \u003d marker.get(_first_key)"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2Fgi4%3D","line":453,"updated":"2013-09-03 23:37:47.000000000","message":"What is this method doing? Why is the first value \"special\" and why is the method recursive?","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":450,"context_line":"        return ret[0]"},{"line_number":451,"context_line":""},{"line_number":452,"context_line":"    @classmethod"},{"line_number":453,"context_line":"    def _recurse_sort_keys(cls, sort_keys, marker, sort_flags):"},{"line_number":454,"context_line":"        _first_key \u003d sort_keys[0]"},{"line_number":455,"context_line":"        _first_flag \u003d sort_flags[0]"},{"line_number":456,"context_line":"        value \u003d marker.get(_first_key)"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FfU4%3D","line":453,"in_reply_to":"AAAASn%2F%2Fgi4%3D","updated":"2013-09-05 07:18:16.000000000","message":"Length of list equaling 1 is the condition to return and out of recurse. So, the first value is \"special\"","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"6ab537ff92473ab940385d24e4867669a35c844c","unresolved":false,"context_lines":[{"line_number":490,"context_line":"            _sort_dirs.append(_sort_dir)"},{"line_number":491,"context_line":"            _sort_flags.append(_sort_flag)"},{"line_number":492,"context_line":""},{"line_number":493,"context_line":"        for _sort_key, _sort_dir in zip(sort_keys, _sort_dirs):"},{"line_number":494,"context_line":"            _all_sort \u003d (_sort_key, _sort_dir)"},{"line_number":495,"context_line":"            all_sort.append(_all_sort)"},{"line_number":496,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FgiY%3D","line":493,"updated":"2013-09-03 23:37:47.000000000","message":"This loop uses zip() to create tuples, unpacks them, makes a new tuple of the results, and then appends the new tuple to a list.\n\nJust use:\n\n  all_sort \u003d list(zip(sort_keys, _sort_dirs))","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":490,"context_line":"            _sort_dirs.append(_sort_dir)"},{"line_number":491,"context_line":"            _sort_flags.append(_sort_flag)"},{"line_number":492,"context_line":""},{"line_number":493,"context_line":"        for _sort_key, _sort_dir in zip(sort_keys, _sort_dirs):"},{"line_number":494,"context_line":"            _all_sort \u003d (_sort_key, _sort_dir)"},{"line_number":495,"context_line":"            all_sort.append(_all_sort)"},{"line_number":496,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FfVY%3D","line":493,"in_reply_to":"AAAASn%2F%2FgiY%3D","updated":"2013-09-05 07:18:16.000000000","message":"Done","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"6ab537ff92473ab940385d24e4867669a35c844c","unresolved":false,"context_lines":[{"line_number":497,"context_line":"        if marker is not None:"},{"line_number":498,"context_line":"            sort_criteria_list \u003d []"},{"line_number":499,"context_line":""},{"line_number":500,"context_line":"            for i in range(0, len(sort_keys)):"},{"line_number":501,"context_line":"                sort_criteria_list.append(cls._recurse_sort_keys("},{"line_number":502,"context_line":"                                          sort_keys[:(len(sort_keys) - i)],"},{"line_number":503,"context_line":"                                          marker,"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FghE%3D","line":500,"updated":"2013-09-03 23:37:47.000000000","message":"Could you add a comment explaining this loop? It looks like it\u0027s very inefficient (looping over a range and recursively (re)processing slices of the keys and flags).","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":497,"context_line":"        if marker is not None:"},{"line_number":498,"context_line":"            sort_criteria_list \u003d []"},{"line_number":499,"context_line":""},{"line_number":500,"context_line":"            for i in range(0, len(sort_keys)):"},{"line_number":501,"context_line":"                sort_criteria_list.append(cls._recurse_sort_keys("},{"line_number":502,"context_line":"                                          sort_keys[:(len(sort_keys) - i)],"},{"line_number":503,"context_line":"                                          marker,"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FfVU%3D","line":500,"in_reply_to":"AAAASn%2F%2FghE%3D","updated":"2013-09-05 07:18:16.000000000","message":"Done","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"6ab537ff92473ab940385d24e4867669a35c844c","unresolved":false,"context_lines":[{"line_number":586,"context_line":"        limit, marker_pair, sort_keys, sort_dirs \u003d\\"},{"line_number":587,"context_line":"            base.split_pagination_parameters(models.Resource, pagination)"},{"line_number":588,"context_line":""},{"line_number":589,"context_line":"        marker_pair, sort_keys \u003d base.keys_translate("},{"line_number":590,"context_line":"            \u0027_id\u0027, models.Resource.get_default_sort_key(),"},{"line_number":591,"context_line":"            marker_pair, sort_keys)"},{"line_number":592,"context_line":"        if marker_pair:"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2Fgg0%3D","line":589,"updated":"2013-09-03 23:37:47.000000000","message":"I\u0027m not sure marker \"pair\" is right any more, is it?","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"303c0e7d9441db8a2bd295e0bdca688d5989c872","unresolved":false,"context_lines":[{"line_number":302,"context_line":""},{"line_number":303,"context_line":"    TRANSLATE_KEYS \u003d {\u0027Resource\u0027: {\u0027resource_id\u0027: \u0027_id\u0027},"},{"line_number":304,"context_line":"                      \u0027Meter\u0027: {\u0027resource_id\u0027: \u0027_id\u0027,"},{"line_number":305,"context_line":"                      \u0027counter_name\u0027: \u0027meter.counter_name\u0027},"},{"line_number":306,"context_line":"                      }"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"    def __init__(self, conf):"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAATH%2F%2FXtQ%3D","line":305,"updated":"2013-10-17 03:48:00.000000000","message":"nitpicking, how about some nicer indention?","commit_id":"8c7784c1b8cec689d56ac9ffe6aeb1fa74ed0866"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"303c0e7d9441db8a2bd295e0bdca688d5989c872","unresolved":false,"context_lines":[{"line_number":469,"context_line":"        ret \u003d []"},{"line_number":470,"context_line":""},{"line_number":471,"context_line":"        if db_collection and model_name and marker_value:"},{"line_number":472,"context_line":"            model \u003d getattr(models, model_name)"},{"line_number":473,"context_line":"            primary_keys, primary_dir \u003d\\"},{"line_number":474,"context_line":"                base.Pagination.get_sort_from_model(model)"},{"line_number":475,"context_line":"            if value_decoding:"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAATH%2F%2FXrY%3D","line":472,"updated":"2013-10-17 03:48:00.000000000","message":"Why we need this here? Why can\u0027t the caller directly pass models.XXX as parameter?","commit_id":"8c7784c1b8cec689d56ac9ffe6aeb1fa74ed0866"},{"author":{"_account_id":7040,"name":"GuoHui LIu","email":"liuguohui@gmail.com","username":"guohliu"},"change_message_id":"3e9febb3bcb79fb847259f8714e1b989cae7a1e4","unresolved":false,"context_lines":[{"line_number":646,"context_line":"        :param resource: Optional resource filter."},{"line_number":647,"context_line":"        :param pagination: Optional pagination query."},{"line_number":648,"context_line":"        \"\"\""},{"line_number":649,"context_line":"        limit, marker_value, sort_keys, sort_dirs \u003d\\"},{"line_number":650,"context_line":"            pagination.split_pagination_parameters(models.Resource)\\"},{"line_number":651,"context_line":"            if pagination else\\"},{"line_number":652,"context_line":"            base.Pagination.default_pagination_parameters(models.Resource)"}],"source_content_type":"text/x-python","patch_set":19,"id":"AAAATH%2F%2FXh4%3D","line":649,"updated":"2013-10-17 05:59:36.000000000","message":"We should avoid to using \\ as possible as we can, in this case multiline with if clause might be cleaner and easier to review, readability is more important than reducing lines of codes here IMHO.","commit_id":"8c7784c1b8cec689d56ac9ffe6aeb1fa74ed0866"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"0793ef63c1b09079b5552eb23e9794eb3ec6c22f","unresolved":false,"context_lines":[{"line_number":474,"context_line":"            primary_keys, primary_dir \u003d\\"},{"line_number":475,"context_line":"                Pagination.get_sort_from_model(model_class)"},{"line_number":476,"context_line":"            if value_decoding:"},{"line_number":477,"context_line":"                marker_value \u003d models.Meter.get_marker_values(marker_value)"},{"line_number":478,"context_line":"            if not isinstance(marker_value, list):"},{"line_number":479,"context_line":"                marker_value \u003d [marker_value]"},{"line_number":480,"context_line":"            if key_translate:"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATX%2F%2F%2FSo%3D","line":477,"updated":"2013-10-23 08:20:19.000000000","message":"It\u0027d be better to change a little bit here to support future other models which has get_marker_values method.","commit_id":"f2eb83161026fd425c05e9c5f1dbcad7345f6b5d"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":452,"context_line":"    @classmethod"},{"line_number":453,"context_line":"    def get_all_marker_value(cls, db_collection, model_class, model_name,"},{"line_number":454,"context_line":"                             marker_value\u003dNone, value_decoding\u003dFalse,"},{"line_number":455,"context_line":"                             sort_keys\u003d[], key_translate\u003dFalse):"},{"line_number":456,"context_line":"        \"\"\"Return all marker values according the value of primary key."},{"line_number":457,"context_line":""},{"line_number":458,"context_line":"        :param db_collection: Database collection that be query."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhd8%3D","line":455,"updated":"2014-01-12 20:57:10.000000000","message":"\"get_all_marker_value\" does not make grammatical sense. \"all\" is plural. \"value\" is singular. Plus, \"value\" really isn\u0027t what this is describing.\n\nHow about \"get_all_marker_documents\" or \"get_all_marker_records\"?\n\nHere, and below (change \"value\" to \"records\" or \"documents\" accordingly)","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":452,"context_line":"    @classmethod"},{"line_number":453,"context_line":"    def get_all_marker_value(cls, db_collection, model_class, model_name,"},{"line_number":454,"context_line":"                             marker_value\u003dNone, value_decoding\u003dFalse,"},{"line_number":455,"context_line":"                             sort_keys\u003d[], key_translate\u003dFalse):"},{"line_number":456,"context_line":"        \"\"\"Return all marker values according the value of primary key."},{"line_number":457,"context_line":""},{"line_number":458,"context_line":"        :param db_collection: Database collection that be query."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FZhU%3D","line":455,"in_reply_to":"AAAAUH%2F%2Fhd8%3D","updated":"2014-01-17 06:55:51.000000000","message":"Done","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":462,"context_line":"        :param value_decoding: Marker value needs decoding or not. This is"},{"line_number":463,"context_line":"                                mainly used by get_meters whose marker"},{"line_number":464,"context_line":"                                value is the combination of resource_id and"},{"line_number":465,"context_line":"                                meter_name."},{"line_number":466,"context_line":"        :param sort_keys: List of attributes bu which results be sorted."},{"line_number":467,"context_line":"        :param key_translate: Need keys translate or not."},{"line_number":468,"context_line":"        return: All marker value according value of primary key and"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhdg%3D","line":465,"updated":"2014-01-12 20:57:10.000000000","message":"This parameter really isn\u0027t necessary. See previous comment about just always doing split(\u0027+\u0027) on the marker query parameter.","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":462,"context_line":"        :param value_decoding: Marker value needs decoding or not. This is"},{"line_number":463,"context_line":"                                mainly used by get_meters whose marker"},{"line_number":464,"context_line":"                                value is the combination of resource_id and"},{"line_number":465,"context_line":"                                meter_name."},{"line_number":466,"context_line":"        :param sort_keys: List of attributes bu which results be sorted."},{"line_number":467,"context_line":"        :param key_translate: Need keys translate or not."},{"line_number":468,"context_line":"        return: All marker value according value of primary key and"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FINE%3D","line":465,"in_reply_to":"AAAAUH%2F%2Fhdg%3D","updated":"2014-01-17 06:55:51.000000000","message":"value_decoding is mainly used for get_meters, for other functions, it is useless.  It has nothing to do with the ValueError raising in split_combined_marker_values(). \n\nFor get_meters, marker_value needs decoding, while others do not. I just want to provide one common interface to all functions here:).","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":476,"context_line":"            if value_decoding:"},{"line_number":477,"context_line":"                marker_value \u003d base.split_combinate_marker_values(marker_value)"},{"line_number":478,"context_line":"            if not isinstance(marker_value, list):"},{"line_number":479,"context_line":"                marker_value \u003d [marker_value]"},{"line_number":480,"context_line":"            if key_translate:"},{"line_number":481,"context_line":"                sort_keys \u003d cls.keys_translate(sort_keys, model_name)"},{"line_number":482,"context_line":"                primary_keys \u003d cls.keys_translate(primary_keys, model_name)"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhd4%3D","line":479,"updated":"2014-01-12 20:57:10.000000000","message":"If you follow my advice from earlier (remove the ValueError raising in split_combined_marker_values()), then you don\u0027t need the above. split(\u0027+\u0027) will *always* return a list.","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":476,"context_line":"            if value_decoding:"},{"line_number":477,"context_line":"                marker_value \u003d base.split_combinate_marker_values(marker_value)"},{"line_number":478,"context_line":"            if not isinstance(marker_value, list):"},{"line_number":479,"context_line":"                marker_value \u003d [marker_value]"},{"line_number":480,"context_line":"            if key_translate:"},{"line_number":481,"context_line":"                sort_keys \u003d cls.keys_translate(sort_keys, model_name)"},{"line_number":482,"context_line":"                primary_keys \u003d cls.keys_translate(primary_keys, model_name)"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FILI%3D","line":479,"in_reply_to":"AAAAUH%2F%2Fhd4%3D","updated":"2014-01-17 06:55:51.000000000","message":"Here, turning marker_value into list is for the following handle. And the reason for this transferring is that get_meters will pass a list in as the result of decoding, while others just pass in one single value as marker_value.","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":574,"context_line":"        return sort_instructions, operation"},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"    @classmethod"},{"line_number":577,"context_line":"    def paginate_query(cls, q, db_collection, limit\u003dNone, marker\u003d[],"},{"line_number":578,"context_line":"                       sort_keys\u003d[], sort_dirs\u003d[]):"},{"line_number":579,"context_line":""},{"line_number":580,"context_line":"        \"\"\"Returns a query result with sorting / pagination."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhdc%3D","line":577,"updated":"2014-01-12 20:57:10.000000000","message":"s/marker/markers/\n\nThe parameters that are lists are plural, not singular.","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":574,"context_line":"        return sort_instructions, operation"},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"    @classmethod"},{"line_number":577,"context_line":"    def paginate_query(cls, q, db_collection, limit\u003dNone, marker\u003d[],"},{"line_number":578,"context_line":"                       sort_keys\u003d[], sort_dirs\u003d[]):"},{"line_number":579,"context_line":""},{"line_number":580,"context_line":"        \"\"\"Returns a query result with sorting / pagination."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FZg4%3D","line":577,"in_reply_to":"AAAAUH%2F%2Fhdc%3D","updated":"2014-01-17 06:55:51.000000000","message":"Done","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":765,"context_line":"                                               sort_keys\u003dsort_keys,"},{"line_number":766,"context_line":"                                               key_translate\u003dTrue)"},{"line_number":767,"context_line":"        sort_keys \u003d self.keys_translate(sort_keys, \u0027Meter\u0027)"},{"line_number":768,"context_line":""},{"line_number":769,"context_line":"        for r in self.paginate_query(q, self.db.resource, limit\u003dlimit,"},{"line_number":770,"context_line":"                                     marker\u003dall_marker,"},{"line_number":771,"context_line":"                                     sort_keys\u003dsort_keys, sort_dirs\u003dsort_dirs):"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhb8%3D","line":768,"updated":"2014-01-12 20:57:10.000000000","message":"I do not see any code in here (or below for the Alarm paginated results) that ensures that **at least one of the sort keys is on a unique column**.\n\nWithout at least one unique column in the sort keys, pagination using marker/limit algorithms cannot be deterministic.\n\nTo see why this is the case, consider the following:\n\n1) The user specifies a sort key/dir of \"timestamp desc\"\n\n2) The user specifies a limit of 10\n\n3) The latest 15 meter records all have the same timestamp\n\nBecause of the above, and because there is only a single sort key (timestamp desc), the following will occur:\n\na) The first page of results will be 10 random records with the same timestamp\n\nb) The \"marker record\" will be the \"last\" random record with the same timestamp as all the other meter records.\n\nc) The second page of results will be indeterminate. It will either contain all ten records that came up on the first page, none of the records that appear on the first page, or something in between. The reason is because the lone search condition that would be generated from the above code is:\n\n WHERE timestamp \u003c\u003d $marker_record_timestamp\n\nAnd since 15 records, including all of the records that may have appeared on the first page, all match the above condition, there is no way that the second page\u0027s results will be deterministic.\n\nThe only way to prevent this from occurring is to ensure that when pagination is used, that at least one of the sort keys is unique.\n\nIf the sort keys were changed from just \"timestamp desc\" to instead \"timestamp desc, meter_id asc\", then the first page of results would be the ten records with the same timestamp, in ascending order of meter ID. The marker record would have the last meter ID of the first page, and the second page\u0027s search conditions would look like this:\n\n WHERE timestamp \u003c\u003d $marker_record_timestamp AND meter_id \u003e $marker_record_meter_id","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":765,"context_line":"                                               sort_keys\u003dsort_keys,"},{"line_number":766,"context_line":"                                               key_translate\u003dTrue)"},{"line_number":767,"context_line":"        sort_keys \u003d self.keys_translate(sort_keys, \u0027Meter\u0027)"},{"line_number":768,"context_line":""},{"line_number":769,"context_line":"        for r in self.paginate_query(q, self.db.resource, limit\u003dlimit,"},{"line_number":770,"context_line":"                                     marker\u003dall_marker,"},{"line_number":771,"context_line":"                                     sort_keys\u003dsort_keys, sort_dirs\u003dsort_dirs):"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FZbo%3D","line":768,"in_reply_to":"AAAAUH%2F%2Fhb8%3D","updated":"2014-01-17 06:55:51.000000000","message":"Yes, you are right. I have a idea that use the primary key.\n\nIf users did not specify sort keys, the default keys and dirs are used; Or else, i will add the primary key at the end of the sort keys from users.\n\nFor example, sort keys from users are [\u0027key1\u0027, \u0027key2\u0027], then the final sort keys list passed to paginate_query is [\u0027key1\u0027, \u0027key2\u0027, \u0027primary_key\u0027]. This will make sure that a unique column is in the sort keys.\n\nIs it make sense?","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":948,"context_line":"                pagination.split_pagination_parameters(models.Alarm)"},{"line_number":949,"context_line":"        else:"},{"line_number":950,"context_line":"            limit, marker_value, sort_keys, sort_dirs \u003d\\"},{"line_number":951,"context_line":"                base.Pagination.default_pagination_parameters(models.Meter)"},{"line_number":952,"context_line":""},{"line_number":953,"context_line":"        all_marker \u003d self.get_all_marker_value(db_collection\u003dself.db.alarm,"},{"line_number":954,"context_line":"                                               model_class\u003dmodels.Alarm,"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhc0%3D","line":951,"updated":"2014-01-12 20:57:10.000000000","message":"The above is injecting the *Meter* default sort keys for the *Alarm* pagination...","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":948,"context_line":"                pagination.split_pagination_parameters(models.Alarm)"},{"line_number":949,"context_line":"        else:"},{"line_number":950,"context_line":"            limit, marker_value, sort_keys, sort_dirs \u003d\\"},{"line_number":951,"context_line":"                base.Pagination.default_pagination_parameters(models.Meter)"},{"line_number":952,"context_line":""},{"line_number":953,"context_line":"        all_marker \u003d self.get_all_marker_value(db_collection\u003dself.db.alarm,"},{"line_number":954,"context_line":"                                               model_class\u003dmodels.Alarm,"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FIK0%3D","line":951,"in_reply_to":"AAAAUH%2F%2Fhc0%3D","updated":"2014-01-17 06:55:51.000000000","message":"Same comments as Line 768","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":507,"context_line":"        if db_collection and model_class and model_name and marker_value:"},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"            primary_keys \u003d base.Pagination.get_sort_from_model(model_class)[0]"},{"line_number":510,"context_line":"            if value_decoding:"},{"line_number":511,"context_line":"                marker_value \u003d base.split_combined_marker_values(marker_value)"},{"line_number":512,"context_line":"            if not isinstance(marker_value, list):"},{"line_number":513,"context_line":"                marker_value \u003d [marker_value]"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFxU%3D","line":510,"updated":"2014-01-17 15:27:09.000000000","message":"No need for this parameter anymore :) base.split_combined_marker_values always returns a list of supplied marker values...","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":510,"context_line":"            if value_decoding:"},{"line_number":511,"context_line":"                marker_value \u003d base.split_combined_marker_values(marker_value)"},{"line_number":512,"context_line":"            if not isinstance(marker_value, list):"},{"line_number":513,"context_line":"                marker_value \u003d [marker_value]"},{"line_number":514,"context_line":"            if key_translate:"},{"line_number":515,"context_line":"                sort_keys \u003d cls.translate_keys(sort_keys, model_name)"},{"line_number":516,"context_line":"                primary_keys \u003d cls.translate_keys(primary_keys, model_name)"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFxQ%3D","line":513,"updated":"2014-01-17 15:27:09.000000000","message":"No need for above two lines :)","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":516,"context_line":"                primary_keys \u003d cls.translate_keys(primary_keys, model_name)"},{"line_number":517,"context_line":"            if primary_keys \u003d\u003d sort_keys:"},{"line_number":518,"context_line":"                #NOTE(fengqian): If sort_keys from user equal the primary"},{"line_number":519,"context_line":"                #keys of database, we only need to return maker_value."},{"line_number":520,"context_line":"                return marker_value"},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"            marker_pair \u003d {}"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFxE%3D","line":519,"updated":"2014-01-17 15:27:09.000000000","message":"++. Good short-circuit optimization.","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3565ea1572c73f828e03c4ba859c4a015d487bad","unresolved":false,"context_lines":[{"line_number":516,"context_line":"                primary_keys \u003d cls.translate_keys(primary_keys, model_name)"},{"line_number":517,"context_line":"            if primary_keys \u003d\u003d sort_keys:"},{"line_number":518,"context_line":"                #NOTE(fengqian): If sort_keys from user equal the primary"},{"line_number":519,"context_line":"                #keys of database, we only need to return maker_value."},{"line_number":520,"context_line":"                return marker_value"},{"line_number":521,"context_line":""},{"line_number":522,"context_line":"            marker_pair \u003d {}"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2B%2FMs%3D","line":519,"in_reply_to":"AAAAUH%2F%2FFxE%3D","updated":"2014-02-10 03:25:35.000000000","message":"Done","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":552,"context_line":"        We use the last item in previous page as the \u0027marker\u0027 for pagination."},{"line_number":553,"context_line":"        So we return values that follow the passed marker in the order."},{"line_number":554,"context_line":"        :param q: The query dict passed in."},{"line_number":555,"context_line":"        :param marker: Values of the last item of the previous page."},{"line_number":556,"context_line":"        :param sort_keys: array of attributes by which results be sorted."},{"line_number":557,"context_line":"        :param sort_dirs: per-column array of sort_dirs, corresponding to"},{"line_number":558,"context_line":"                           sort_keys."}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFwc%3D","line":555,"updated":"2014-01-17 15:27:09.000000000","message":"Please change marker to markers (plural), to match the sort_keys and sort_dirs plural parameters.","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3565ea1572c73f828e03c4ba859c4a015d487bad","unresolved":false,"context_lines":[{"line_number":552,"context_line":"        We use the last item in previous page as the \u0027marker\u0027 for pagination."},{"line_number":553,"context_line":"        So we return values that follow the passed marker in the order."},{"line_number":554,"context_line":"        :param q: The query dict passed in."},{"line_number":555,"context_line":"        :param marker: Values of the last item of the previous page."},{"line_number":556,"context_line":"        :param sort_keys: array of attributes by which results be sorted."},{"line_number":557,"context_line":"        :param sort_dirs: per-column array of sort_dirs, corresponding to"},{"line_number":558,"context_line":"                           sort_keys."}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2B%2FN4%3D","line":555,"in_reply_to":"AAAAUH%2F%2FFwc%3D","updated":"2014-02-10 03:25:35.000000000","message":"Done","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":570,"context_line":"            #{\u0027k3\u0027: {\u0027$lt\u0027: \u0027v3\u0027}, \u0027k2\u0027: {\u0027eq\u0027: \u0027v2\u0027}, \u0027k1\u0027: {\u0027eq\u0027: \u0027v1\u0027}},"},{"line_number":571,"context_line":"            #{\u0027k2\u0027: {\u0027$gt\u0027: \u0027v2\u0027}, \u0027k1\u0027: {\u0027eq\u0027: \u0027v1\u0027}},"},{"line_number":572,"context_line":"            #{\u0027k1\u0027: {\u0027$lt\u0027: \u0027v1\u0027}} with \u0027OR\u0027 operation."},{"line_number":573,"context_line":"            #Each recurse will generate one items of three."},{"line_number":574,"context_line":"                sort_criteria_list.append(cls._recurse_sort_keys("},{"line_number":575,"context_line":"                                          sort_keys[:(len(sort_keys) - i)],"},{"line_number":576,"context_line":"                                          marker[:(len(marker) - i)],"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFvU%3D","line":573,"updated":"2014-01-17 15:27:09.000000000","message":"nit: Great comment, but please align above comment with the line below, not the \"for i in..\" line.","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3565ea1572c73f828e03c4ba859c4a015d487bad","unresolved":false,"context_lines":[{"line_number":570,"context_line":"            #{\u0027k3\u0027: {\u0027$lt\u0027: \u0027v3\u0027}, \u0027k2\u0027: {\u0027eq\u0027: \u0027v2\u0027}, \u0027k1\u0027: {\u0027eq\u0027: \u0027v1\u0027}},"},{"line_number":571,"context_line":"            #{\u0027k2\u0027: {\u0027$gt\u0027: \u0027v2\u0027}, \u0027k1\u0027: {\u0027eq\u0027: \u0027v1\u0027}},"},{"line_number":572,"context_line":"            #{\u0027k1\u0027: {\u0027$lt\u0027: \u0027v1\u0027}} with \u0027OR\u0027 operation."},{"line_number":573,"context_line":"            #Each recurse will generate one items of three."},{"line_number":574,"context_line":"                sort_criteria_list.append(cls._recurse_sort_keys("},{"line_number":575,"context_line":"                                          sort_keys[:(len(sort_keys) - i)],"},{"line_number":576,"context_line":"                                          marker[:(len(marker) - i)],"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2B%2FOc%3D","line":573,"in_reply_to":"AAAAUH%2F%2FFvU%3D","updated":"2014-02-10 03:25:35.000000000","message":"Done","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"}],"ceilometer/storage/models.py":[{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"df67203e9ade90e3bb883be989781f595dac77dc","unresolved":false,"context_lines":[{"line_number":118,"context_line":"                       )"},{"line_number":119,"context_line":""},{"line_number":120,"context_line":"    @staticmethod"},{"line_number":121,"context_line":"    def get_default_sort_key():"},{"line_number":122,"context_line":"        return [\u0027resource_id\u0027]"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FhrE%3D","line":121,"updated":"2013-09-03 19:59:33.000000000","message":"These new methods need to be defined for the base class with either defaults or as abstract methods.","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"c1d9ebb22fb3b1af83d4d2a943cbf5f8923d041a","unresolved":false,"context_lines":[{"line_number":120,"context_line":"    @staticmethod"},{"line_number":121,"context_line":"    def get_default_sort_key():"},{"line_number":122,"context_line":"        return [\u0027resource_id\u0027]"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @staticmethod"},{"line_number":125,"context_line":"    def get_default_sort_dir():"},{"line_number":126,"context_line":"        return [\u0027desc\u0027]"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2Fkck%3D","line":123,"updated":"2013-09-03 11:45:48.000000000","message":"Not need to build a method for all of that then, just use a class attribute.","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"df67203e9ade90e3bb883be989781f595dac77dc","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        return [\u0027resource_id\u0027]"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @staticmethod"},{"line_number":125,"context_line":"    def get_default_sort_dir():"},{"line_number":126,"context_line":"        return [\u0027desc\u0027]"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FhpA%3D","line":125,"updated":"2013-09-03 19:59:33.000000000","message":"Even better, because the key and direction are related, combine get_default_sort_key() and get_default_sort_dir() to a single list of tuples with names and directions:\n\n  DEFAULT_SORT \u003d [(\u0027resource_id\u0027, \u0027desc\u0027)]\n\nWhy descending?","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":122,"context_line":"        return [\u0027resource_id\u0027]"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @staticmethod"},{"line_number":125,"context_line":"    def get_default_sort_dir():"},{"line_number":126,"context_line":"        return [\u0027desc\u0027]"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2Fe7U%3D","line":125,"in_reply_to":"AAAASn%2F%2FhpA%3D","updated":"2013-09-05 07:18:16.000000000","message":"Done","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"df67203e9ade90e3bb883be989781f595dac77dc","unresolved":false,"context_lines":[{"line_number":126,"context_line":"        return [\u0027desc\u0027]"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    @staticmethod"},{"line_number":129,"context_line":"    def get_marker_pair(marker_value):"},{"line_number":130,"context_line":"        return {\u0027resource_id\u0027: marker_value}"},{"line_number":131,"context_line":""},{"line_number":132,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FhrM%3D","line":129,"updated":"2013-09-03 19:59:33.000000000","message":"We need to stop calling this a \"marker pair\" because there\u0027s only one value.\n\nI would expect get_marker() to return the value for an instance of the model. This method seems more like it is intended to return the search parameters given a marker value, is that right?","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"df67203e9ade90e3bb883be989781f595dac77dc","unresolved":false,"context_lines":[{"line_number":178,"context_line":"                       )"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"    @staticmethod"},{"line_number":181,"context_line":"    def get_meter_marker_values(marker_value):"},{"line_number":182,"context_line":"        #NOTE(Fengqian): We could not find a primary key for database"},{"line_number":183,"context_line":"        #model of Meter. So, we will use the combination of resource_id"},{"line_number":184,"context_line":"        #and meter_name as a fake key and it needs to parse the marker_value"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FhqE%3D","line":181,"updated":"2013-09-03 19:59:33.000000000","message":"I don\u0027t see why this is a separate method? The name has the redundant \"meter\" in it, and it\u0027s really just 1 line that could be handled inline in get_marker_pair().","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":178,"context_line":"                       )"},{"line_number":179,"context_line":""},{"line_number":180,"context_line":"    @staticmethod"},{"line_number":181,"context_line":"    def get_meter_marker_values(marker_value):"},{"line_number":182,"context_line":"        #NOTE(Fengqian): We could not find a primary key for database"},{"line_number":183,"context_line":"        #model of Meter. So, we will use the combination of resource_id"},{"line_number":184,"context_line":"        #and meter_name as a fake key and it needs to parse the marker_value"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FfiE%3D","line":181,"in_reply_to":"AAAASn%2F%2FhqE%3D","updated":"2013-09-05 07:18:16.000000000","message":"Done","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"df67203e9ade90e3bb883be989781f595dac77dc","unresolved":false,"context_lines":[{"line_number":196,"context_line":"    def get_default_sort_dir():"},{"line_number":197,"context_line":"        return [\u0027desc\u0027, \u0027desc\u0027]"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    @staticmethod"},{"line_number":200,"context_line":"    def get_marker_pair(marker_value):"},{"line_number":201,"context_line":"        resource_id, meter_name \u003d Meter.get_meter_marker_values(marker_value)"},{"line_number":202,"context_line":"        return {\u0027resource_id\u0027: resource_id,"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2Fhqk%3D","line":199,"updated":"2013-09-03 19:59:33.000000000","message":"Don\u0027t define this as a static method and then use the class by name to invoke another method of the class. Either combine the methods, use a class method, or use a regular method.","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"0303a15acd39a271c9f1d8add71a1949eb5e9011","unresolved":false,"context_lines":[{"line_number":196,"context_line":"    def get_default_sort_dir():"},{"line_number":197,"context_line":"        return [\u0027desc\u0027, \u0027desc\u0027]"},{"line_number":198,"context_line":""},{"line_number":199,"context_line":"    @staticmethod"},{"line_number":200,"context_line":"    def get_marker_pair(marker_value):"},{"line_number":201,"context_line":"        resource_id, meter_name \u003d Meter.get_meter_marker_values(marker_value)"},{"line_number":202,"context_line":"        return {\u0027resource_id\u0027: resource_id,"}],"source_content_type":"text/x-python","patch_set":16,"id":"AAAASn%2F%2FfiI%3D","line":199,"in_reply_to":"AAAASn%2F%2Fhqk%3D","updated":"2013-09-05 07:18:16.000000000","message":"Done","commit_id":"6fe04437c0c36320b01f9b0427f6704721594738"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":301,"context_line":"        ALARM_ALARM: \u0027alarm_actions\u0027,"},{"line_number":302,"context_line":"    }"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    DEFAULT_SORT \u003d [(\u0027alarm_id\u0027, \u0027asc\u0027)]"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    \"\"\""},{"line_number":307,"context_line":"    An alarm to monitor."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FhdA%3D","line":304,"updated":"2014-01-12 20:57:10.000000000","message":"Here, and above...\n\nIt seems to me that the ID value of the model, in ascending direction, is the opposite of what would be expected from a monitoring/metering API. Generally, I would expect the *latest* records to be returned, not the earliest.","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":301,"context_line":"        ALARM_ALARM: \u0027alarm_actions\u0027,"},{"line_number":302,"context_line":"    }"},{"line_number":303,"context_line":""},{"line_number":304,"context_line":"    DEFAULT_SORT \u003d [(\u0027alarm_id\u0027, \u0027asc\u0027)]"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"    \"\"\""},{"line_number":307,"context_line":"    An alarm to monitor."}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FZdE%3D","line":304,"in_reply_to":"AAAAUH%2F%2FhdA%3D","updated":"2014-01-17 06:55:51.000000000","message":"The reason why use ascending as default is quite simple:). \n\nIn the codes paginate_query of sqlalchemy, it uses  ascending as default. To keep in line  with it, we use ascending here.\n\nhttps://github.com/openstack/oslo-incubator/blob/master/openstack/common/db/sqlalchemy/utils.py#L103\nBecause it seems more easy here, we do not want to change the common code of openstack.  It takes more time to sync up.","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"}],"ceilometer/tests/storage/test_base.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"0dd1821066754e5fe03871d5850359ef607748e2","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            pagination.split_pagination_parameters(model_class\u003dmodels.Meter)"},{"line_number":132,"context_line":"        self.assertEqual(limit, 10)"},{"line_number":133,"context_line":"        self.assertEqual(sort_keys, [\u0027resource_id\u0027, \u0027counter_name\u0027])"},{"line_number":134,"context_line":"        self.assertEqual(sort_dirs, [\u0027desc\u0027, \u0027desc\u0027])"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2Fhb0%3D","line":134,"updated":"2014-01-12 20:57:10.000000000","message":"We need many more tests that verify situations where sort key is not unique (see long explanation as to why in previous comments about not ensuring at least one unique sort key).","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"b5e4c2deec830c7ffac40b0520071173d43b001f","unresolved":false,"context_lines":[{"line_number":131,"context_line":"            pagination.split_pagination_parameters(model_class\u003dmodels.Meter)"},{"line_number":132,"context_line":"        self.assertEqual(limit, 10)"},{"line_number":133,"context_line":"        self.assertEqual(sort_keys, [\u0027resource_id\u0027, \u0027counter_name\u0027])"},{"line_number":134,"context_line":"        self.assertEqual(sort_dirs, [\u0027desc\u0027, \u0027desc\u0027])"}],"source_content_type":"text/x-python","patch_set":28,"id":"AAAAUH%2F%2FIIs%3D","line":134,"in_reply_to":"AAAAUH%2F%2Fhb0%3D","updated":"2014-01-17 06:55:51.000000000","message":"Like i said, if i add the primary key at the end of sort keys list from users to ensure that one unique sort keys contained, does it still necessary to add more test cases? Please give your advice:)","commit_id":"cc54e46845291f162a9a68223fed9d83bcfb80fd"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        self.assertEqual(keys, [\u0027resource_id\u0027])"},{"line_number":69,"context_line":"        self.assertEqual(dirs, [\u0027asc\u0027])"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def test_split_combinated_marker_values(self):"},{"line_number":72,"context_line":"        marker_value_string \u003d \u0027resource-id+meter-name\u0027"},{"line_number":73,"context_line":"        marker_values \u003d base64.encodestring(marker_value_string)"},{"line_number":74,"context_line":"        ret \u003d base.split_combined_marker_values(marker_values)"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFuQ%3D","line":71,"updated":"2014-01-17 15:27:09.000000000","message":"s/combinated/combined :) combinated isn\u0027t a word.","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3565ea1572c73f828e03c4ba859c4a015d487bad","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        self.assertEqual(keys, [\u0027resource_id\u0027])"},{"line_number":69,"context_line":"        self.assertEqual(dirs, [\u0027asc\u0027])"},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"    def test_split_combinated_marker_values(self):"},{"line_number":72,"context_line":"        marker_value_string \u003d \u0027resource-id+meter-name\u0027"},{"line_number":73,"context_line":"        marker_values \u003d base64.encodestring(marker_value_string)"},{"line_number":74,"context_line":"        ret \u003d base.split_combined_marker_values(marker_values)"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2B%2FPk%3D","line":71,"in_reply_to":"AAAAUH%2F%2FFuQ%3D","updated":"2014-02-10 03:25:35.000000000","message":"Done","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"}],"ceilometer/tests/storage/test_storage_scenarios.py":[{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"d29034d77b3a8acbdb829005f056b3411f2f97a1","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def test_get_resources_ordering_all(self):"},{"line_number":400,"context_line":"        if cfg.CONF.database.connection.startswith(\u0027mongodb://\u0027):"},{"line_number":401,"context_line":"            self.skipTest(\"Default sort instructions changed for mongodb\")"},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"        resources \u003d list(self.conn.get_resources())"},{"line_number":404,"context_line":"        expected \u003d set(["}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAATn%2F98Z8%3D","line":401,"updated":"2013-12-04 06:47:28.000000000","message":"why skip this?","commit_id":"7aee1b6f07502183c27bd835046fcc9ff262628d"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"dd870bb2bad7fba8d20624110fa9c287a3f667b4","unresolved":false,"context_lines":[{"line_number":398,"context_line":""},{"line_number":399,"context_line":"    def test_get_resources_ordering_all(self):"},{"line_number":400,"context_line":"        if cfg.CONF.database.connection.startswith(\u0027mongodb://\u0027):"},{"line_number":401,"context_line":"            self.skipTest(\"Default sort instructions changed for mongodb\")"},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"        resources \u003d list(self.conn.get_resources())"},{"line_number":404,"context_line":"        expected \u003d set(["}],"source_content_type":"text/x-python","patch_set":25,"id":"AAAATn%2F93L8%3D","line":401,"in_reply_to":"AAAATn%2F98Z8%3D","updated":"2013-12-05 05:32:13.000000000","message":"After added pagination to Mongodb, the default sort key is only \u0027resource_id\u0027, while the previous default sort keys are [\u0027user_id\u0027, \u0027project_id\u0027, \u0027timestamp\u0027].\nSo, this test is not work for mongodb.","commit_id":"7aee1b6f07502183c27bd835046fcc9ff262628d"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"655c881555fa2cf16093f561d0298f147e845975","unresolved":false,"context_lines":[{"line_number":2067,"context_line":"#\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":2068,"context_line":"#        self.assertEqual(set([alarm.rule[\u0027meter_name\u0027] for alarm in alarms]),"},{"line_number":2069,"context_line":"#                         set([\u0027test.fourty\u0027, \u0027test.one\u0027, \u0027test.five\u0027]))"},{"line_number":2070,"context_line":"#\u003e\u003e\u003e\u003e\u003e\u003e\u003e 3ccc216... Change pagination related methods of mongodb and db2"},{"line_number":2071,"context_line":""},{"line_number":2072,"context_line":"    def test_update(self):"},{"line_number":2073,"context_line":"        self.add_some_alarms()"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2FFqk%3D","line":2070,"updated":"2014-01-17 15:27:09.000000000","message":"Need to clean up the above conflict marker :)","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3565ea1572c73f828e03c4ba859c4a015d487bad","unresolved":false,"context_lines":[{"line_number":2067,"context_line":"#\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":2068,"context_line":"#        self.assertEqual(set([alarm.rule[\u0027meter_name\u0027] for alarm in alarms]),"},{"line_number":2069,"context_line":"#                         set([\u0027test.fourty\u0027, \u0027test.one\u0027, \u0027test.five\u0027]))"},{"line_number":2070,"context_line":"#\u003e\u003e\u003e\u003e\u003e\u003e\u003e 3ccc216... Change pagination related methods of mongodb and db2"},{"line_number":2071,"context_line":""},{"line_number":2072,"context_line":"    def test_update(self):"},{"line_number":2073,"context_line":"        self.add_some_alarms()"}],"source_content_type":"text/x-python","patch_set":29,"id":"AAAAUH%2F%2B%2FPc%3D","line":2070,"in_reply_to":"AAAAUH%2F%2FFqk%3D","updated":"2014-02-10 03:25:35.000000000","message":"Done","commit_id":"6db25c427b027f1f8b14b127326fb30c8d830d01"}],"tests/storage/base.py":[{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"e19ec0e677acc7b73db66fbf5182397b94d29797","unresolved":false,"context_lines":[{"line_number":352,"context_line":"        pagination \u003d Pagination(sort_keys\u003d[\u0027user_id\u0027],"},{"line_number":353,"context_line":"                                sort_dirs\u003d[\u0027asc\u0027], marker_pair\u003dmarker_pair)"},{"line_number":354,"context_line":"        results \u003d list(self.conn.get_resources(pagination\u003dpagination))"},{"line_number":355,"context_line":"        self.assertEqual(len(results), 5)"},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"    def test_get_resources_paginate(self):"},{"line_number":358,"context_line":"        marker_pair \u003d {\u0027user_id\u0027: \u0027user-id-4\u0027}"}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAASX%2F%2F1W8%3D","line":355,"updated":"2013-08-26 15:52:13.000000000","message":"This does not actually test the marker and sort ordering worked properly at all... there should be assertions for the *exact* records expected to be returned given the supplied marker, sort key and limit.","commit_id":"031cc9f2659e35974ee14a69275b81ad20f696b5"}],"tests/storage/test_base.py":[{"author":{"_account_id":2472,"name":"Doug Hellmann","email":"dhellmann@redhat.com","username":"doug-hellmann"},"change_message_id":"4543cc5c0aeb1c58e8b936782bc3283a83e984ed","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        self.assertEqual(sort_keys, [])"},{"line_number":70,"context_line":"        self.assertEqual(sort_dirs, [])"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        pagination \u003d Pagination(primary_sort_dir\u003d\u0027desc\u0027,"},{"line_number":73,"context_line":"                                marker_value\u003d\u0027foo\u0027)"},{"line_number":74,"context_line":"        limit, marker_pair, sort_keys, sort_dirs \u003d\\"},{"line_number":75,"context_line":"            base.split_pagination_parameters(model_name\u003d\u0027test\u0027,"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fplg%3D","line":72,"updated":"2013-09-01 14:39:33.000000000","message":"Each of these test cases should be a separate method.","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":7642,"name":"Fengqian Gao","email":"fengqian.gao@intel.com","username":"Fengqian"},"change_message_id":"3d33b684ff8de8d1a484808c12f155851f7ed43d","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        self.assertEqual(sort_keys, [])"},{"line_number":70,"context_line":"        self.assertEqual(sort_dirs, [])"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"        pagination \u003d Pagination(primary_sort_dir\u003d\u0027desc\u0027,"},{"line_number":73,"context_line":"                                marker_value\u003d\u0027foo\u0027)"},{"line_number":74,"context_line":"        limit, marker_pair, sort_keys, sort_dirs \u003d\\"},{"line_number":75,"context_line":"            base.split_pagination_parameters(model_name\u003d\u0027test\u0027,"}],"source_content_type":"text/x-python","patch_set":12,"id":"AAAASn%2F%2Fo2s%3D","line":72,"in_reply_to":"AAAASn%2F%2Fplg%3D","updated":"2013-09-02 07:41:58.000000000","message":"Done","commit_id":"df3130e6ab46cf0011c815ea59cc512913dde9af"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"e3b9fcbaa9b68b0dfbdaaa7f3c8889183e9293bc","unresolved":false,"context_lines":[{"line_number":56,"context_line":""},{"line_number":57,"context_line":"class PaginationBaseTest(test_base.TestCase):"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    def test_model_default_sort_keys_dirs(self):"},{"line_number":60,"context_line":"        self.assertEquals(models.Alarm.DEFAULT_SORT, [(\u0027alarm_id\u0027, \u0027asc\u0027)])"},{"line_number":61,"context_line":"        self.assertEquals(models.Resource.DEFAULT_SORT,"},{"line_number":62,"context_line":"                          [(\u0027resource_id\u0027, \u0027asc\u0027)])"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATX%2F%2F%2FcI%3D","line":59,"updated":"2013-10-23 07:48:17.000000000","message":"Just wondering if this is necessary? What\u0027s the purpose of this test? This seems not testing any implementation logic or flow.","commit_id":"f2eb83161026fd425c05e9c5f1dbcad7345f6b5d"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"e3b9fcbaa9b68b0dfbdaaa7f3c8889183e9293bc","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        self.assertEquals(sort_keys, [\u0027resource_id\u0027])"},{"line_number":77,"context_line":"        self.assertEquals(sort_dirs, [\u0027asc\u0027])"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"    def test_get_meter_marker_values(self):"},{"line_number":80,"context_line":"        marker_value_string \u003d \u0027resource-id+meter-name\u0027"},{"line_number":81,"context_line":"        marker_values \u003d base64.encodestring(marker_value_string)"},{"line_number":82,"context_line":"        ret \u003d models.Meter.get_marker_values(marker_values)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATX%2F%2F%2Fbg%3D","line":79,"updated":"2013-10-23 07:48:17.000000000","message":"Should we move this test into test_models.py?","commit_id":"f2eb83161026fd425c05e9c5f1dbcad7345f6b5d"}],"tests/storage/test_impl_mongodb.py":[{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"3cc814c1230b4c55c58d839788808eca0ec719ba","unresolved":false,"context_lines":[{"line_number":94,"context_line":"            ret \u003d impl_mongodb.Connection._get_marker(self.conn.db.resource,"},{"line_number":95,"context_line":"                                                      marker_pair)"},{"line_number":96,"context_line":"            self.assertEqual(ret[\u0027project_id\u0027], \u0027project-id-foo\u0027)"},{"line_number":97,"context_line":"        except NoResultFound:"},{"line_number":98,"context_line":"            self.assertTrue(True)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAASX%2F%2F3SM%3D","line":97,"updated":"2013-08-26 03:15:21.000000000","message":"Does this mean a negative test? If we expect to get the NoResultFound exception, we should use assertRaises() here.","commit_id":"031cc9f2659e35974ee14a69275b81ad20f696b5"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"3cc814c1230b4c55c58d839788808eca0ec719ba","unresolved":false,"context_lines":[{"line_number":266,"context_line":"            ret \u003d impl_mongodb.Connection._get_marker(self.conn.db.alarm,"},{"line_number":267,"context_line":"                                                      marker_pair)"},{"line_number":268,"context_line":"            self.assertEqual(ret[\u0027counter_name\u0027], \u0027counter_name-foo\u0027)"},{"line_number":269,"context_line":"        except NoResultFound:"},{"line_number":270,"context_line":"            self.assertTrue(True)"},{"line_number":271,"context_line":""},{"line_number":272,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"AAAASX%2F%2F3SE%3D","line":269,"updated":"2013-08-26 03:15:21.000000000","message":"Does this mean a negative test? If we expect to get the NoResultFound exception, we should use assertRaises() here.","commit_id":"031cc9f2659e35974ee14a69275b81ad20f696b5"}],"tests/storage/test_storage_scenarios.py":[{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"50cf56929a8efa176932a4a5fc82e6cad8d26640","unresolved":false,"context_lines":[{"line_number":397,"context_line":""},{"line_number":398,"context_line":"    def test_get_resources_ordering_all(self):"},{"line_number":399,"context_line":"        if cfg.CONF.database.connection.startswith(\u0027mongodb://\u0027):"},{"line_number":400,"context_line":"            return"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"        resources \u003d list(self.conn.get_resources())"},{"line_number":403,"context_line":"        expected \u003d set(["}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATX%2F%2F%2FX8%3D","line":400,"updated":"2013-10-23 07:55:23.000000000","message":"how about use testtools.TestCase.skipTest?","commit_id":"f2eb83161026fd425c05e9c5f1dbcad7345f6b5d"},{"author":{"_account_id":4491,"name":"Lianhao Lu","email":"llh_misc@outlook.com","username":"lianhao-lu"},"change_message_id":"50cf56929a8efa176932a4a5fc82e6cad8d26640","unresolved":false,"context_lines":[{"line_number":411,"context_line":"    def test_get_resources_ordering_single(self):"},{"line_number":412,"context_line":"        if cfg.CONF.database.connection.startswith(\u0027mongodb://\u0027):"},{"line_number":413,"context_line":"            return"},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"        resource \u003d list(self.conn.get_resources(resource\u003d\u0027resource-id-2\u0027))[0]"},{"line_number":416,"context_line":"        self.assertEqual(resource.resource_id, \u0027resource-id-2\u0027)"},{"line_number":417,"context_line":"        self.assertEqual(resource.metadata[\u0027tag\u0027], \u0027sample-8\u0027)"}],"source_content_type":"text/x-python","patch_set":22,"id":"AAAATX%2F%2F%2FX4%3D","line":414,"updated":"2013-10-23 07:55:23.000000000","message":"how about use testtools.TestCase.skipTest?","commit_id":"f2eb83161026fd425c05e9c5f1dbcad7345f6b5d"}]}
