Commit 554957d4 authored by Dan Jensen's avatar Dan Jensen

Add order_by updated_at to Deployments API

This allows order_by updated_at on the Deployments API so users can
query for the most recent updates. It adds a database index to ensure
the feature is performant.
parent 7b06d27f
---
title: Allow order_by updated_at in Deployments API
merge_request: 19658
author:
type: added
# frozen_string_literal: true
class AddIndexOnDeploymentsUpdatedAt < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_COLUMNS = [:project_id, :updated_at]
disable_ddl_transaction!
def up
add_concurrent_index(:deployments, INDEX_COLUMNS)
end
def down
remove_concurrent_index(:deployments, INDEX_COLUMNS)
end
end
...@@ -1297,6 +1297,7 @@ ActiveRecord::Schema.define(version: 2019_11_12_221821) do ...@@ -1297,6 +1297,7 @@ ActiveRecord::Schema.define(version: 2019_11_12_221821) do
t.index ["project_id", "iid"], name: "index_deployments_on_project_id_and_iid", unique: true t.index ["project_id", "iid"], name: "index_deployments_on_project_id_and_iid", unique: true
t.index ["project_id", "status", "created_at"], name: "index_deployments_on_project_id_and_status_and_created_at" t.index ["project_id", "status", "created_at"], name: "index_deployments_on_project_id_and_status_and_created_at"
t.index ["project_id", "status"], name: "index_deployments_on_project_id_and_status" t.index ["project_id", "status"], name: "index_deployments_on_project_id_and_status"
t.index ["project_id", "updated_at"], name: "index_deployments_on_project_id_and_updated_at"
end end
create_table "description_versions", force: :cascade do |t| create_table "description_versions", force: :cascade do |t|
......
...@@ -11,7 +11,7 @@ GET /projects/:id/deployments ...@@ -11,7 +11,7 @@ GET /projects/:id/deployments
| Attribute | Type | Required | Description | | Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------| |-----------|---------|----------|---------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `order_by`| string | no | Return deployments ordered by `id` or `iid` or `created_at` or `ref` fields. Default is `id` | | `order_by`| string | no | Return deployments ordered by `id` or `iid` or `created_at` or `updated_at` or `ref` fields. Default is `id` |
| `sort` | string | no | Return deployments sorted in `asc` or `desc` order. Default is `asc` | | `sort` | string | no | Return deployments sorted in `asc` or `desc` order. Default is `asc` |
```bash ```bash
......
...@@ -17,7 +17,7 @@ module API ...@@ -17,7 +17,7 @@ module API
end end
params do params do
use :pagination use :pagination
optional :order_by, type: String, values: %w[id iid created_at ref], default: 'id', desc: 'Return deployments ordered by `id` or `iid` or `created_at` or `ref`' optional :order_by, type: String, values: %w[id iid created_at updated_at ref], default: 'id', desc: 'Return deployments ordered by `id` or `iid` or `created_at` or `updated_at` or `ref`'
optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)' optional :sort, type: String, values: %w[asc desc], default: 'asc', desc: 'Sort by asc (ascending) or desc (descending)'
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
......
...@@ -12,9 +12,9 @@ describe API::Deployments do ...@@ -12,9 +12,9 @@ describe API::Deployments do
describe 'GET /projects/:id/deployments' do describe 'GET /projects/:id/deployments' do
let(:project) { create(:project) } let(:project) { create(:project) }
let!(:deployment_1) { create(:deployment, :success, project: project, iid: 11, ref: 'master', created_at: Time.now) } let!(:deployment_1) { create(:deployment, :success, project: project, iid: 11, ref: 'master', created_at: Time.now, updated_at: Time.now) }
let!(:deployment_2) { create(:deployment, :success, project: project, iid: 12, ref: 'feature', created_at: 1.day.ago) } let!(:deployment_2) { create(:deployment, :success, project: project, iid: 12, ref: 'feature', created_at: 1.day.ago, updated_at: 2.hours.ago) }
let!(:deployment_3) { create(:deployment, :success, project: project, iid: 8, ref: 'patch', created_at: 2.days.ago) } let!(:deployment_3) { create(:deployment, :success, project: project, iid: 8, ref: 'patch', created_at: 2.days.ago, updated_at: 1.hour.ago) }
context 'as member of the project' do context 'as member of the project' do
it 'returns projects deployments sorted by id asc' do it 'returns projects deployments sorted by id asc' do
...@@ -57,6 +57,8 @@ describe API::Deployments do ...@@ -57,6 +57,8 @@ describe API::Deployments do
'iid' | 'desc' | [:deployment_2, :deployment_1, :deployment_3] 'iid' | 'desc' | [:deployment_2, :deployment_1, :deployment_3]
'ref' | 'asc' | [:deployment_2, :deployment_1, :deployment_3] 'ref' | 'asc' | [:deployment_2, :deployment_1, :deployment_3]
'ref' | 'desc' | [:deployment_3, :deployment_1, :deployment_2] 'ref' | 'desc' | [:deployment_3, :deployment_1, :deployment_2]
'updated_at' | 'asc' | [:deployment_2, :deployment_3, :deployment_1]
'updated_at' | 'desc' | [:deployment_1, :deployment_3, :deployment_2]
end end
with_them do with_them do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment