From 040b5a674a6f97ec7e039c6dc39c878a519788fd Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Mon, 18 Sep 2017 15:56:58 -0700 Subject: [PATCH] Add db.instance_get_by_sort_filters() This adds a method to the DB API that lets us query out the next instance for a sort query, but without a marker UUID. If the marker is from another cell, we'll need to resume the pagination sequence based on the sort keys and the values from the marker instance. This adds the method and a test to be used later. Change-Id: Ib0e63ec0dd12c2feff562311bd7f69234cf43a1b --- nova/db/api.py | 5 +++++ nova/db/sqlalchemy/api.py | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/nova/db/api.py b/nova/db/api.py index 275340dba..b7f6bcf3b 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -782,6 +782,11 @@ def instance_get_all_by_filters_sort(context, filters, limit=None, sort_dirs=sort_dirs) +def instance_get_by_sort_filters(context, sort_keys, sort_dirs, values): + return IMPL.instance_get_by_sort_filters(context, sort_keys, sort_dirs, + values) + + def instance_get_active_by_window_joined(context, begin, end=None, project_id=None, host=None, columns_to_join=None, limit=None, diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 4e69506c5..ccc8dd232 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -2275,6 +2275,32 @@ def instance_get_all_by_filters_sort(context, filters, limit=None, marker=None, return _instances_fill_metadata(context, query_prefix.all(), manual_joins) +@require_context +@pick_context_manager_reader_allow_async +def instance_get_by_sort_filters(context, sort_keys, sort_dirs, values): + """Attempt to get a single instance based on a combination of sort + keys, directions and filter values. This is used to try to find a + marker instance when we don't have a marker uuid. + + This returns just a uuid of the instance that matched. + """ + query = context.session.query(models.Instance.uuid) + for skey, sdir, val in zip(sort_keys, sort_dirs, values): + col = getattr(models.Instance, skey) + if sdir == 'asc': + query = query.filter(col >= val).order_by(col) + else: + query = query.filter(col <= val).order_by(col.desc()) + + # We can't raise InstanceNotFound because we don't have a uuid to + # be looking for, so just return nothing if no match. + result = query.limit(1).first() + if result: + return result[0] + else: + return result + + def _db_connection_type(db_connection): """Returns a lowercase symbol for the db type.