Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions components/dashboard/src/admin/WorkspacesSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function WorkspaceSearch(props: Props) {
<path fillRule="evenodd" clipRule="evenodd" d="M6 2a4 4 0 100 8 4 4 0 000-8zM0 6a6 6 0 1110.89 3.477l4.817 4.816a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 010 6z" fill="#A8A29E" />
</svg>
</div>
<input type="search" placeholder="Search context URLs" onKeyDown={(ke) => ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
<input type="search" placeholder="Search workspaces" onKeyDown={(ke) => ke.key === 'Enter' && search() } onChange={(v) => { setSearchTerm(v.target.value) }} />
</div>
<button disabled={searching} onClick={search}>Search</button>
</div>
Expand Down Expand Up @@ -125,4 +125,4 @@ function WorkspaceEntry(p: { ws: WorkspaceAndInstance }) {
</div>
</div>
</Link>;
}
}
20 changes: 14 additions & 6 deletions components/gitpod-db/src/typeorm/workspace-db-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -698,14 +698,22 @@ export abstract class AbstractTypeORMWorkspaceDBImpl extends AbstractWorkspaceDB


public async findAllWorkspaceAndInstances(offset: number, limit: number, orderBy: keyof WorkspaceAndInstance, orderDir: "ASC" | "DESC", ownerId?: string, searchTerm?: string): Promise<{ total: number, rows: WorkspaceAndInstance[] }> {
let joinConditions = [];
let joinConditionParams: any = {};
let whereConditions = ['wsi2.id IS NULL'];
let whereConditionParams: any = {};

if (!!ownerId) {
joinConditions.push("ws.ownerId = :ownerId");
joinConditionParams.ownerId = ownerId;
// If an owner id is provided only search for workspaces belonging to that user.
whereConditions.push("ws.ownerId = :ownerId");
whereConditionParams.ownerId = ownerId;
}

if (!!searchTerm) {
joinConditions.push(`ws.contextURL LIKE '%${searchTerm}%'`);
// If a search term is provided perform a wildcard search in the context url or exact match on the workspace id (aka workspace name) or the instance id.
whereConditions.push([
`ws.contextURL LIKE '%${searchTerm}%'`,
`ws.id = '${searchTerm}'`,
`wsi.id = '${searchTerm}'`
].join(' OR '))
}

let orderField: string = orderBy;
Expand All @@ -731,7 +739,7 @@ export abstract class AbstractTypeORMWorkspaceDBImpl extends AbstractWorkspaceDB
'wsi2.workspaceId = ws.id',
'(wsi.creationTime < wsi2.creationTime OR (wsi.creationTime = wsi2.creationTime AND wsi.id < wsi2.id))'
].join(' AND '))
.where([ ... joinConditions, 'wsi2.id IS NULL' ].join(' AND '), joinConditionParams)
.where(whereConditions.join(' AND '), whereConditionParams)
.orderBy(orderField, orderDir)
.take(limit)
.skip(offset);
Expand Down
43 changes: 43 additions & 0 deletions components/gitpod-db/src/workspace-db.spec.db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -301,5 +301,48 @@ import { DBWorkspaceInstance } from './typeorm/entity/db-workspace-instance';
expect(workspaceAndInstance.instanceId).to.eq(this.wsi2.id)
});
}

@test(timeout(10000))
public async testFindAllWorkspaceAndInstances_workspaceId() {
await this.db.transaction(async db => {
await Promise.all([
db.store(this.ws),
db.storeInstance(this.wsi1),
db.store(this.ws2),
db.storeInstance(this.ws2i1),
]);
const dbResult = await db.findAllWorkspaceAndInstances(0, 10, "workspaceId", "DESC", undefined, this.ws2.id);
// It should only find one workspace instance
expect(dbResult.total).to.eq(1);

// It should find the workspace with the queried id
const workspaceAndInstance = dbResult.rows[0]
expect(workspaceAndInstance.workspaceId).to.eq(this.ws2.id)
});
}

@test(timeout(10000))
public async testFindAllWorkspaceAndInstances_instanceId() {
await this.db.transaction(async db => {
await Promise.all([
db.store(this.ws),
db.storeInstance(this.wsi1),
db.storeInstance(this.wsi2),
db.store(this.ws2),
db.storeInstance(this.ws2i1),
]);
const dbResult = await db.findAllWorkspaceAndInstances(0, 10, "instanceId", "DESC", undefined, this.wsi1.id);

// It should only find one workspace instance
expect(dbResult.total).to.eq(1);

// It should find the workspace with the queried id
const workspaceAndInstance = dbResult.rows[0]
expect(workspaceAndInstance.workspaceId).to.eq(this.ws.id)

// It should select the workspace instance that was queried, not the most recent one
expect(workspaceAndInstance.instanceId).to.eq(this.wsi1.id)
});
}
Comment on lines +305 to +346
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: Haven't tried running these but thanks for adding these tests! 🌟

}
module.exports = new WorkspaceDBSpec()