mirror of
https://pagure.io/fm-orchestrator.git
synced 2026-04-10 14:20:00 +08:00
Allow filtering on all table columns
This commit is contained in:
64
README.rst
64
README.rst
@@ -492,29 +492,27 @@ parameters::
|
||||
Filtering module builds
|
||||
-----------------------
|
||||
|
||||
The module-builds can be filtered by a variety of GET parameters. These
|
||||
parameters are:
|
||||
The module builds can be filtered by a variety of GET parameters. Some of these
|
||||
parameters include:
|
||||
|
||||
- ``name`` - Shows builds of modules with a particular name (e.g.
|
||||
``name=testmodule``)
|
||||
- ``koji_tag`` - Shows builds tagged with a particular Koji tag (e.g.
|
||||
``koji_tag=module-984ed60dd37b9361``)
|
||||
- ``owner`` - Shows builds submitted by a particular user (e.g.
|
||||
``owner=mprahl``)
|
||||
- ``state`` - Shows builds in a particular state (can be the state name or
|
||||
the state ID) (e.g. ``state=done``)
|
||||
- ``submitted_before`` - Shows builds that were submitted before a particular
|
||||
Zulu ISO 8601 timestamp (e.g. ``submitted_before=2016-08-23T09:40:07Z``)
|
||||
- ``submitted_after`` - Shows builds that were submitted after a particular
|
||||
Zulu ISO 8601 timestamp (e.g. ``submitted_after=2016-08-22T09:40:07Z``)
|
||||
- ``modified_before`` - Shows builds that were modified before a particular
|
||||
Zulu ISO 8601 timestamp (e.g. ``modified_before=2016-08-23T09:40:07Z``)
|
||||
- ``modified_after`` - Shows builds that were modified after a particular
|
||||
Zulu ISO 8601 timestamp (e.g. ``modified_after=2016-08-22T09:40:07Z``)
|
||||
- ``completed_before`` - Shows builds that were completed before a particular
|
||||
Zulu ISO 8601 timestamp (e.g. ``completed_before=2016-08-22T09:40:07Z``)
|
||||
- ``completed_after`` - Shows builds that were completed after a particular
|
||||
Zulu ISO 8601 timestamp (e.g. ``completed_after=2016-08-23T09:40:07Z``)
|
||||
- ``batch``
|
||||
- ``cg_build_koji_tag``
|
||||
- ``completed_after`` (Zulu ISO 8601 format e.g. ``completed_after=2016-08-23T09:40:07Z``)
|
||||
- ``completed_before`` (Zulu ISO 8601 format e.g. ``completed_before=2016-08-22T09:40:07Z``)
|
||||
- ``koji_tag``
|
||||
- ``modified_after`` (Zulu ISO 8601 format e.g. ``modified_after=2016-08-22T09:40:07Z``)
|
||||
- ``modified_before`` (Zulu ISO 8601 format e.g. ``modified_before=2016-08-23T09:40:07Z``)
|
||||
- ``name``
|
||||
- ``new_repo_task_id``
|
||||
- ``owner``
|
||||
- ``rebuild_strategy``
|
||||
- ``scmurl``
|
||||
- ``state`` (can be the state name or the state ID e.g. ``state=done``)
|
||||
- ``state_reason``
|
||||
- ``stream``
|
||||
- ``submitted_after`` (Zulu ISO 8601 format e.g. ``submitted_after=2016-08-22T09:40:07Z``)
|
||||
- ``submitted_before`` (Zulu ISO 8601 format e.g. ``submitted_before=2016-08-23T09:40:07Z``)
|
||||
- ``version``
|
||||
|
||||
An example of querying the "module-builds" resource with the "state",
|
||||
and the "submitted_before" parameters::
|
||||
@@ -658,6 +656,28 @@ parameters::
|
||||
}
|
||||
|
||||
|
||||
|
||||
Filtering component builds
|
||||
--------------------------
|
||||
|
||||
The component builds can be filtered by a variety of GET parameters. Some of these
|
||||
parameters include:
|
||||
|
||||
- ``batch``
|
||||
- ``build_time_only`` (boolean e.g. "true" or "false")
|
||||
- ``format``
|
||||
- ``module_id`` or ``module_build``
|
||||
- ``nvr``
|
||||
- ``package``
|
||||
- ``ref``
|
||||
- ``scmurl``
|
||||
- ``state``
|
||||
- ``state_reason``
|
||||
- ``tagged`` (boolean e.g. "true" or "false")
|
||||
- ``tagged_in_final`` (boolean e.g. "true" or "false")
|
||||
- ``task_id``
|
||||
|
||||
|
||||
Listing about
|
||||
-------------
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ import yaml
|
||||
|
||||
from flask import request, url_for, Response
|
||||
from datetime import datetime
|
||||
from sqlalchemy.sql.sqltypes import Boolean as sqlalchemy_boolean
|
||||
|
||||
from module_build_service import log, models
|
||||
from module_build_service.errors import (ValidationError, UnprocessableEntity,
|
||||
@@ -436,6 +437,15 @@ def _add_order_by_clause(flask_request, query, column_source):
|
||||
return query.order_by(column)
|
||||
|
||||
|
||||
def str_to_bool(value):
|
||||
"""
|
||||
Parses a string to determine its boolean value
|
||||
:param value: a string
|
||||
:return: a boolean
|
||||
"""
|
||||
return value.lower() in ["true", "1"]
|
||||
|
||||
|
||||
def filter_component_builds(flask_request):
|
||||
"""
|
||||
Returns a flask_sqlalchemy.Pagination object based on the request parameters
|
||||
@@ -443,8 +453,15 @@ def filter_component_builds(flask_request):
|
||||
:return: flask_sqlalchemy.Pagination
|
||||
"""
|
||||
search_query = dict()
|
||||
state = flask_request.args.get('state', None)
|
||||
for key in request.args.keys():
|
||||
# Only filter on valid database columns
|
||||
if key in models.ComponentBuild.__table__.columns.keys():
|
||||
if isinstance(models.ComponentBuild.__table__.columns[key].type, sqlalchemy_boolean):
|
||||
search_query[key] = str_to_bool(flask_request.args[key])
|
||||
else:
|
||||
search_query[key] = flask_request.args[key]
|
||||
|
||||
state = flask_request.args.get('state', None)
|
||||
if state:
|
||||
if state.isdigit():
|
||||
search_query['state'] = state
|
||||
@@ -454,11 +471,9 @@ def filter_component_builds(flask_request):
|
||||
else:
|
||||
raise ValidationError('An invalid state was supplied')
|
||||
|
||||
# Lookup module_build from task_id, ref, format, nvr or tagged attribute
|
||||
# of a component build.
|
||||
for key in ['task_id', 'ref', 'nvr', 'format', 'tagged']:
|
||||
if flask_request.args.get(key, None):
|
||||
search_query[key] = flask_request.args[key]
|
||||
# Allow the user to specify the module build ID with a more intuitive key name
|
||||
if 'module_build' in flask_request.args:
|
||||
search_query['module_id'] = flask_request.args['module_build']
|
||||
|
||||
query = models.ComponentBuild.query
|
||||
|
||||
@@ -479,8 +494,14 @@ def filter_module_builds(flask_request):
|
||||
:return: flask_sqlalchemy.Pagination
|
||||
"""
|
||||
search_query = dict()
|
||||
state = flask_request.args.get('state', None)
|
||||
special_columns = ['time_submitted', 'time_modified', 'time_completed', 'state']
|
||||
for key in request.args.keys():
|
||||
# Only filter on valid database columns but skip columns that are treated specially or
|
||||
# ignored
|
||||
if key not in special_columns and key in models.ModuleBuild.__table__.columns.keys():
|
||||
search_query[key] = flask_request.args[key]
|
||||
|
||||
state = flask_request.args.get('state', None)
|
||||
if state:
|
||||
if state.isdigit():
|
||||
search_query['state'] = state
|
||||
@@ -490,10 +511,6 @@ def filter_module_builds(flask_request):
|
||||
else:
|
||||
raise ValidationError('An invalid state was supplied')
|
||||
|
||||
for key in ['name', 'owner', 'koji_tag']:
|
||||
if flask_request.args.get(key, None):
|
||||
search_query[key] = flask_request.args[key]
|
||||
|
||||
query = models.ModuleBuild.query
|
||||
|
||||
if search_query:
|
||||
|
||||
@@ -365,10 +365,9 @@ class TestViews(unittest.TestCase):
|
||||
self.assertEquals(data['meta']['total'], 0)
|
||||
|
||||
def test_query_component_builds_filter_tagged(self):
|
||||
rv = self.client.get('/module-build-service/1/component-builds/'
|
||||
'?tagged=this-filter-query-should-return-zero-items')
|
||||
rv = self.client.get('/module-build-service/1/component-builds/?tagged=true')
|
||||
data = json.loads(rv.data)
|
||||
self.assertEquals(data['meta']['total'], 0)
|
||||
self.assertEquals(data['meta']['total'], 40)
|
||||
|
||||
def test_query_component_builds_filter_nvr(self):
|
||||
rv = self.client.get(
|
||||
@@ -446,6 +445,17 @@ class TestViews(unittest.TestCase):
|
||||
data = json.loads(rv.data)
|
||||
self.assertEquals(data['meta']['total'], 4)
|
||||
|
||||
def test_query_builds_filter_nsv(self):
|
||||
rv = self.client.get(
|
||||
'/module-build-service/1/module-builds/?name=postgressql&stream=1&version=2')
|
||||
data = json.loads(rv.data)
|
||||
# TODO: The nsv should really be unique in the test data
|
||||
for item in data['items']:
|
||||
self.assertEqual(item['name'], 'postgressql')
|
||||
self.assertEqual(item['stream'], '1')
|
||||
self.assertEqual(item['version'], '2')
|
||||
self.assertEquals(data['meta']['total'], 10)
|
||||
|
||||
def test_query_builds_filter_invalid_date(self):
|
||||
rv = self.client.get(
|
||||
'/module-build-service/1/module-builds/?modified_after=2016-09-03T12:25:00-05:00')
|
||||
|
||||
Reference in New Issue
Block a user