0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-03-11 02:23:09 -05:00

feat(mobile)!: batched full/initial sync (#4840)

* feat(mobile): batched full/initial sync

* use OptionalBetween

* skip/take as integer

---------

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
Fynn Petersen-Frey 2023-11-06 18:40:43 +01:00 committed by GitHub
parent 26fd9d7e5f
commit 21f2d3058a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 189 additions and 63 deletions

View file

@ -6695,16 +6695,18 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
}, },
/** /**
* Get all AssetEntity belong to the user * Get all AssetEntity belong to the user
* @param {number} [skip]
* @param {number} [take]
* @param {string} [userId] * @param {string} [userId]
* @param {boolean} [isFavorite] * @param {boolean} [isFavorite]
* @param {boolean} [isArchived] * @param {boolean} [isArchived]
* @param {number} [skip]
* @param {string} [updatedAfter] * @param {string} [updatedAfter]
* @param {string} [updatedBefore]
* @param {string} [ifNoneMatch] ETag of data already cached on the client * @param {string} [ifNoneMatch] ETag of data already cached on the client
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
getAllAssets: async (userId?: string, isFavorite?: boolean, isArchived?: boolean, skip?: number, updatedAfter?: string, ifNoneMatch?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { getAllAssets: async (skip?: number, take?: number, userId?: string, isFavorite?: boolean, isArchived?: boolean, updatedAfter?: string, updatedBefore?: string, ifNoneMatch?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/asset`; const localVarPath = `/asset`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -6726,6 +6728,14 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
// http bearer authentication required // http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration) await setBearerAuthToObject(localVarHeaderParameter, configuration)
if (skip !== undefined) {
localVarQueryParameter['skip'] = skip;
}
if (take !== undefined) {
localVarQueryParameter['take'] = take;
}
if (userId !== undefined) { if (userId !== undefined) {
localVarQueryParameter['userId'] = userId; localVarQueryParameter['userId'] = userId;
} }
@ -6738,16 +6748,18 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
localVarQueryParameter['isArchived'] = isArchived; localVarQueryParameter['isArchived'] = isArchived;
} }
if (skip !== undefined) {
localVarQueryParameter['skip'] = skip;
}
if (updatedAfter !== undefined) { if (updatedAfter !== undefined) {
localVarQueryParameter['updatedAfter'] = (updatedAfter as any instanceof Date) ? localVarQueryParameter['updatedAfter'] = (updatedAfter as any instanceof Date) ?
(updatedAfter as any).toISOString() : (updatedAfter as any).toISOString() :
updatedAfter; updatedAfter;
} }
if (updatedBefore !== undefined) {
localVarQueryParameter['updatedBefore'] = (updatedBefore as any instanceof Date) ?
(updatedBefore as any).toISOString() :
updatedBefore;
}
if (ifNoneMatch != null) { if (ifNoneMatch != null) {
localVarHeaderParameter['if-none-match'] = String(ifNoneMatch); localVarHeaderParameter['if-none-match'] = String(ifNoneMatch);
} }
@ -8066,17 +8078,19 @@ export const AssetApiFp = function(configuration?: Configuration) {
}, },
/** /**
* Get all AssetEntity belong to the user * Get all AssetEntity belong to the user
* @param {number} [skip]
* @param {number} [take]
* @param {string} [userId] * @param {string} [userId]
* @param {boolean} [isFavorite] * @param {boolean} [isFavorite]
* @param {boolean} [isArchived] * @param {boolean} [isArchived]
* @param {number} [skip]
* @param {string} [updatedAfter] * @param {string} [updatedAfter]
* @param {string} [updatedBefore]
* @param {string} [ifNoneMatch] ETag of data already cached on the client * @param {string} [ifNoneMatch] ETag of data already cached on the client
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async getAllAssets(userId?: string, isFavorite?: boolean, isArchived?: boolean, skip?: number, updatedAfter?: string, ifNoneMatch?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AssetResponseDto>>> { async getAllAssets(skip?: number, take?: number, userId?: string, isFavorite?: boolean, isArchived?: boolean, updatedAfter?: string, updatedBefore?: string, ifNoneMatch?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AssetResponseDto>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAssets(userId, isFavorite, isArchived, skip, updatedAfter, ifNoneMatch, options); const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAssets(skip, take, userId, isFavorite, isArchived, updatedAfter, updatedBefore, ifNoneMatch, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
}, },
/** /**
@ -8421,7 +8435,7 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
* @throws {RequiredError} * @throws {RequiredError}
*/ */
getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig): AxiosPromise<Array<AssetResponseDto>> { getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig): AxiosPromise<Array<AssetResponseDto>> {
return localVarFp.getAllAssets(requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.skip, requestParameters.updatedAfter, requestParameters.ifNoneMatch, options).then((request) => request(axios, basePath)); return localVarFp.getAllAssets(requestParameters.skip, requestParameters.take, requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.updatedAfter, requestParameters.updatedBefore, requestParameters.ifNoneMatch, options).then((request) => request(axios, basePath));
}, },
/** /**
* Get a single asset\'s information * Get a single asset\'s information
@ -8719,6 +8733,20 @@ export interface AssetApiDownloadFileRequest {
* @interface AssetApiGetAllAssetsRequest * @interface AssetApiGetAllAssetsRequest
*/ */
export interface AssetApiGetAllAssetsRequest { export interface AssetApiGetAllAssetsRequest {
/**
*
* @type {number}
* @memberof AssetApiGetAllAssets
*/
readonly skip?: number
/**
*
* @type {number}
* @memberof AssetApiGetAllAssets
*/
readonly take?: number
/** /**
* *
* @type {string} * @type {string}
@ -8742,17 +8770,17 @@ export interface AssetApiGetAllAssetsRequest {
/** /**
* *
* @type {number} * @type {string}
* @memberof AssetApiGetAllAssets * @memberof AssetApiGetAllAssets
*/ */
readonly skip?: number readonly updatedAfter?: string
/** /**
* *
* @type {string} * @type {string}
* @memberof AssetApiGetAllAssets * @memberof AssetApiGetAllAssets
*/ */
readonly updatedAfter?: string readonly updatedBefore?: string
/** /**
* ETag of data already cached on the client * ETag of data already cached on the client
@ -9430,7 +9458,7 @@ export class AssetApi extends BaseAPI {
* @memberof AssetApi * @memberof AssetApi
*/ */
public getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig) { public getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig) {
return AssetApiFp(this.configuration).getAllAssets(requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.skip, requestParameters.updatedAfter, requestParameters.ifNoneMatch, options).then((request) => request(this.axios, this.basePath)); return AssetApiFp(this.configuration).getAllAssets(requestParameters.skip, requestParameters.take, requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.updatedAfter, requestParameters.updatedBefore, requestParameters.ifNoneMatch, options).then((request) => request(this.axios, this.basePath));
} }
/** /**

View file

@ -62,20 +62,31 @@ class AssetService {
/// Returns `null` if the server state did not change, else list of assets /// Returns `null` if the server state did not change, else list of assets
Future<List<Asset>?> _getRemoteAssets(User user) async { Future<List<Asset>?> _getRemoteAssets(User user) async {
const int chunkSize = 5000;
try { try {
final DateTime now = DateTime.now().toUtc();
final List<Asset> allAssets = [];
for (int i = 0;; i += chunkSize) {
final List<AssetResponseDto>? assets = final List<AssetResponseDto>? assets =
await _apiService.assetApi.getAllAssets( await _apiService.assetApi.getAllAssets(
userId: user.id, userId: user.id,
// updatedBefore is important! without it we could
// a) get the same Asset multiple times in different versions (when
// the asset is modified while the chunks are loaded from the server)
// b) miss assets when new assets are inserted in between the calls
updatedBefore: now,
skip: i,
take: chunkSize,
); );
if (assets == null) { if (assets == null) {
return null; return null;
} else if (assets.isNotEmpty && assets.first.ownerId != user.id) {
log.warning("Make sure that server and app versions match!"
" The server returned assets for user ${assets.first.ownerId}"
" while requesting assets of user ${user.id}");
return null;
} }
return assets.map(Asset.remote).toList(); allAssets.addAll(assets.map(Asset.remote));
if (assets.length < chunkSize) {
break;
}
}
return allAssets;
} catch (error, stack) { } catch (error, stack) {
log.severe( log.severe(
'Error while getting remote assets: ${error.toString()}', 'Error while getting remote assets: ${error.toString()}',

View file

@ -197,7 +197,7 @@ class SyncService {
User user, User user,
FutureOr<List<Asset>?> Function(User user) loadAssets, FutureOr<List<Asset>?> Function(User user) loadAssets,
) async { ) async {
final DateTime now = DateTime.now(); final DateTime now = DateTime.now().toUtc();
final List<Asset>? remote = await loadAssets(user); final List<Asset>? remote = await loadAssets(user);
if (remote == null) { if (remote == null) {
return false; return false;
@ -210,6 +210,10 @@ class SyncService {
assert(inDb.isSorted(Asset.compareByChecksum), "inDb not sorted!"); assert(inDb.isSorted(Asset.compareByChecksum), "inDb not sorted!");
remote.sort(Asset.compareByChecksum); remote.sort(Asset.compareByChecksum);
// filter our duplicates that might be introduced by the chunked retrieval
remote.uniqueConsecutive(compare: Asset.compareByChecksum);
final (toAdd, toUpdate, toRemove) = _diffAssets(remote, inDb, remote: true); final (toAdd, toUpdate, toRemove) = _diffAssets(remote, inDb, remote: true);
if (toAdd.isEmpty && toUpdate.isEmpty && toRemove.isEmpty) { if (toAdd.isEmpty && toUpdate.isEmpty && toRemove.isEmpty) {
await _updateUserAssetsETag(user, now); await _updateUserAssetsETag(user, now);
@ -759,6 +763,12 @@ class SyncService {
final List<Asset> toAdd = []; final List<Asset> toAdd = [];
final List<Asset> toUpdate = []; final List<Asset> toUpdate = [];
final List<Asset> toRemove = []; final List<Asset> toRemove = [];
if (assets.isEmpty || inDb.isEmpty) {
// fast path for trivial cases: halfes memory usage during initial sync
return assets.isEmpty
? (toAdd, toUpdate, inDb) // remove all from DB
: (assets, toUpdate, toRemove); // add all assets
}
diffSortedListsSync( diffSortedListsSync(
inDb, inDb,
assets, assets,

View file

@ -374,7 +374,7 @@ void (empty response body)
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) [[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
# **getAllAssets** # **getAllAssets**
> List<AssetResponseDto> getAllAssets(userId, isFavorite, isArchived, skip, updatedAfter, ifNoneMatch) > List<AssetResponseDto> getAllAssets(skip, take, userId, isFavorite, isArchived, updatedAfter, updatedBefore, ifNoneMatch)
@ -399,15 +399,17 @@ import 'package:openapi/api.dart';
//defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction); //defaultApiClient.getAuthentication<HttpBearerAuth>('bearer').setAccessToken(yourTokenGeneratorFunction);
final api_instance = AssetApi(); final api_instance = AssetApi();
final skip = 56; // int |
final take = 56; // int |
final userId = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String | final userId = 38400000-8cf0-11bd-b23e-10b96e4ef00d; // String |
final isFavorite = true; // bool | final isFavorite = true; // bool |
final isArchived = true; // bool | final isArchived = true; // bool |
final skip = 8.14; // num |
final updatedAfter = 2013-10-20T19:20:30+01:00; // DateTime | final updatedAfter = 2013-10-20T19:20:30+01:00; // DateTime |
final updatedBefore = 2013-10-20T19:20:30+01:00; // DateTime |
final ifNoneMatch = ifNoneMatch_example; // String | ETag of data already cached on the client final ifNoneMatch = ifNoneMatch_example; // String | ETag of data already cached on the client
try { try {
final result = api_instance.getAllAssets(userId, isFavorite, isArchived, skip, updatedAfter, ifNoneMatch); final result = api_instance.getAllAssets(skip, take, userId, isFavorite, isArchived, updatedAfter, updatedBefore, ifNoneMatch);
print(result); print(result);
} catch (e) { } catch (e) {
print('Exception when calling AssetApi->getAllAssets: $e\n'); print('Exception when calling AssetApi->getAllAssets: $e\n');
@ -418,11 +420,13 @@ try {
Name | Type | Description | Notes Name | Type | Description | Notes
------------- | ------------- | ------------- | ------------- ------------- | ------------- | ------------- | -------------
**skip** | **int**| | [optional]
**take** | **int**| | [optional]
**userId** | **String**| | [optional] **userId** | **String**| | [optional]
**isFavorite** | **bool**| | [optional] **isFavorite** | **bool**| | [optional]
**isArchived** | **bool**| | [optional] **isArchived** | **bool**| | [optional]
**skip** | **num**| | [optional]
**updatedAfter** | **DateTime**| | [optional] **updatedAfter** | **DateTime**| | [optional]
**updatedBefore** | **DateTime**| | [optional]
**ifNoneMatch** | **String**| ETag of data already cached on the client | [optional] **ifNoneMatch** | **String**| ETag of data already cached on the client | [optional]
### Return type ### Return type

View file

@ -309,19 +309,23 @@ class AssetApi {
/// ///
/// Parameters: /// Parameters:
/// ///
/// * [int] skip:
///
/// * [int] take:
///
/// * [String] userId: /// * [String] userId:
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// ///
/// * [bool] isArchived: /// * [bool] isArchived:
/// ///
/// * [num] skip:
///
/// * [DateTime] updatedAfter: /// * [DateTime] updatedAfter:
/// ///
/// * [DateTime] updatedBefore:
///
/// * [String] ifNoneMatch: /// * [String] ifNoneMatch:
/// ETag of data already cached on the client /// ETag of data already cached on the client
Future<Response> getAllAssetsWithHttpInfo({ String? userId, bool? isFavorite, bool? isArchived, num? skip, DateTime? updatedAfter, String? ifNoneMatch, }) async { Future<Response> getAllAssetsWithHttpInfo({ int? skip, int? take, String? userId, bool? isFavorite, bool? isArchived, DateTime? updatedAfter, DateTime? updatedBefore, String? ifNoneMatch, }) async {
// ignore: prefer_const_declarations // ignore: prefer_const_declarations
final path = r'/asset'; final path = r'/asset';
@ -332,6 +336,12 @@ class AssetApi {
final headerParams = <String, String>{}; final headerParams = <String, String>{};
final formParams = <String, String>{}; final formParams = <String, String>{};
if (skip != null) {
queryParams.addAll(_queryParams('', 'skip', skip));
}
if (take != null) {
queryParams.addAll(_queryParams('', 'take', take));
}
if (userId != null) { if (userId != null) {
queryParams.addAll(_queryParams('', 'userId', userId)); queryParams.addAll(_queryParams('', 'userId', userId));
} }
@ -341,12 +351,12 @@ class AssetApi {
if (isArchived != null) { if (isArchived != null) {
queryParams.addAll(_queryParams('', 'isArchived', isArchived)); queryParams.addAll(_queryParams('', 'isArchived', isArchived));
} }
if (skip != null) {
queryParams.addAll(_queryParams('', 'skip', skip));
}
if (updatedAfter != null) { if (updatedAfter != null) {
queryParams.addAll(_queryParams('', 'updatedAfter', updatedAfter)); queryParams.addAll(_queryParams('', 'updatedAfter', updatedAfter));
} }
if (updatedBefore != null) {
queryParams.addAll(_queryParams('', 'updatedBefore', updatedBefore));
}
if (ifNoneMatch != null) { if (ifNoneMatch != null) {
headerParams[r'if-none-match'] = parameterToString(ifNoneMatch); headerParams[r'if-none-match'] = parameterToString(ifNoneMatch);
@ -370,20 +380,24 @@ class AssetApi {
/// ///
/// Parameters: /// Parameters:
/// ///
/// * [int] skip:
///
/// * [int] take:
///
/// * [String] userId: /// * [String] userId:
/// ///
/// * [bool] isFavorite: /// * [bool] isFavorite:
/// ///
/// * [bool] isArchived: /// * [bool] isArchived:
/// ///
/// * [num] skip:
///
/// * [DateTime] updatedAfter: /// * [DateTime] updatedAfter:
/// ///
/// * [DateTime] updatedBefore:
///
/// * [String] ifNoneMatch: /// * [String] ifNoneMatch:
/// ETag of data already cached on the client /// ETag of data already cached on the client
Future<List<AssetResponseDto>?> getAllAssets({ String? userId, bool? isFavorite, bool? isArchived, num? skip, DateTime? updatedAfter, String? ifNoneMatch, }) async { Future<List<AssetResponseDto>?> getAllAssets({ int? skip, int? take, String? userId, bool? isFavorite, bool? isArchived, DateTime? updatedAfter, DateTime? updatedBefore, String? ifNoneMatch, }) async {
final response = await getAllAssetsWithHttpInfo( userId: userId, isFavorite: isFavorite, isArchived: isArchived, skip: skip, updatedAfter: updatedAfter, ifNoneMatch: ifNoneMatch, ); final response = await getAllAssetsWithHttpInfo( skip: skip, take: take, userId: userId, isFavorite: isFavorite, isArchived: isArchived, updatedAfter: updatedAfter, updatedBefore: updatedBefore, ifNoneMatch: ifNoneMatch, );
if (response.statusCode >= HttpStatus.badRequest) { if (response.statusCode >= HttpStatus.badRequest) {
throw ApiException(response.statusCode, await _decodeBodyBytes(response)); throw ApiException(response.statusCode, await _decodeBodyBytes(response));
} }

View file

@ -53,7 +53,7 @@ void main() {
// Get all AssetEntity belong to the user // Get all AssetEntity belong to the user
// //
//Future<List<AssetResponseDto>> getAllAssets({ String userId, bool isFavorite, bool isArchived, num skip, DateTime updatedAfter, String ifNoneMatch }) async //Future<List<AssetResponseDto>> getAllAssets({ int skip, int take, String userId, bool isFavorite, bool isArchived, DateTime updatedAfter, DateTime updatedBefore, String ifNoneMatch }) async
test('test getAllAssets', () async { test('test getAllAssets', () async {
// TODO // TODO
}); });

View file

@ -914,6 +914,22 @@
"description": "Get all AssetEntity belong to the user", "description": "Get all AssetEntity belong to the user",
"operationId": "getAllAssets", "operationId": "getAllAssets",
"parameters": [ "parameters": [
{
"name": "skip",
"required": false,
"in": "query",
"schema": {
"type": "integer"
}
},
{
"name": "take",
"required": false,
"in": "query",
"schema": {
"type": "integer"
}
},
{ {
"name": "userId", "name": "userId",
"required": false, "required": false,
@ -940,15 +956,16 @@
} }
}, },
{ {
"name": "skip", "name": "updatedAfter",
"required": false, "required": false,
"in": "query", "in": "query",
"schema": { "schema": {
"type": "number" "format": "date-time",
"type": "string"
} }
}, },
{ {
"name": "updatedAfter", "name": "updatedBefore",
"required": false, "required": false,
"in": "query", "in": "query",
"schema": { "schema": {

View file

@ -1,8 +1,8 @@
import { AssetCreate } from '@app/domain'; import { AssetCreate } from '@app/domain';
import { AssetEntity } from '@app/infra/entities'; import { AssetEntity } from '@app/infra/entities';
import OptionalBetween from '@app/infra/utils/optional-between.util';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { MoreThan } from 'typeorm';
import { In } from 'typeorm/find-options/operator/In'; import { In } from 'typeorm/find-options/operator/In';
import { Repository } from 'typeorm/repository/Repository'; import { Repository } from 'typeorm/repository/Repository';
import { AssetSearchDto } from './dto/asset-search.dto'; import { AssetSearchDto } from './dto/asset-search.dto';
@ -129,7 +129,7 @@ export class AssetRepository implements IAssetRepository {
isVisible: true, isVisible: true,
isFavorite: dto.isFavorite, isFavorite: dto.isFavorite,
isArchived: dto.isArchived, isArchived: dto.isArchived,
updatedAt: dto.updatedAfter ? MoreThan(dto.updatedAfter) : undefined, updatedAt: OptionalBetween(dto.updatedAfter, dto.updatedBefore),
}, },
relations: { relations: {
exifInfo: true, exifInfo: true,
@ -137,6 +137,7 @@ export class AssetRepository implements IAssetRepository {
stack: true, stack: true,
}, },
skip: dto.skip || 0, skip: dto.skip || 0,
take: dto.take,
order: { order: {
fileCreatedAt: 'DESC', fileCreatedAt: 'DESC',
}, },

View file

@ -1,7 +1,7 @@
import { Optional, toBoolean } from '@app/domain'; import { Optional, toBoolean } from '@app/domain';
import { ApiProperty } from '@nestjs/swagger'; import { ApiProperty } from '@nestjs/swagger';
import { Transform, Type } from 'class-transformer'; import { Transform, Type } from 'class-transformer';
import { IsBoolean, IsDate, IsNotEmpty, IsNumber, IsUUID } from 'class-validator'; import { IsBoolean, IsDate, IsInt, IsNotEmpty, IsUUID } from 'class-validator';
export class AssetSearchDto { export class AssetSearchDto {
@Optional() @Optional()
@ -17,9 +17,17 @@ export class AssetSearchDto {
isArchived?: boolean; isArchived?: boolean;
@Optional() @Optional()
@IsNumber() @IsInt()
@Type(() => Number)
@ApiProperty({ type: 'integer' })
skip?: number; skip?: number;
@Optional()
@IsInt()
@Type(() => Number)
@ApiProperty({ type: 'integer' })
take?: number;
@Optional() @Optional()
@IsUUID('4') @IsUUID('4')
@ApiProperty({ format: 'uuid' }) @ApiProperty({ format: 'uuid' })
@ -29,4 +37,9 @@ export class AssetSearchDto {
@IsDate() @IsDate()
@Type(() => Date) @Type(() => Date)
updatedAfter?: Date; updatedAfter?: Date;
@Optional()
@IsDate()
@Type(() => Date)
updatedBefore?: Date;
} }

View file

@ -6695,16 +6695,18 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
}, },
/** /**
* Get all AssetEntity belong to the user * Get all AssetEntity belong to the user
* @param {number} [skip]
* @param {number} [take]
* @param {string} [userId] * @param {string} [userId]
* @param {boolean} [isFavorite] * @param {boolean} [isFavorite]
* @param {boolean} [isArchived] * @param {boolean} [isArchived]
* @param {number} [skip]
* @param {string} [updatedAfter] * @param {string} [updatedAfter]
* @param {string} [updatedBefore]
* @param {string} [ifNoneMatch] ETag of data already cached on the client * @param {string} [ifNoneMatch] ETag of data already cached on the client
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
getAllAssets: async (userId?: string, isFavorite?: boolean, isArchived?: boolean, skip?: number, updatedAfter?: string, ifNoneMatch?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => { getAllAssets: async (skip?: number, take?: number, userId?: string, isFavorite?: boolean, isArchived?: boolean, updatedAfter?: string, updatedBefore?: string, ifNoneMatch?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/asset`; const localVarPath = `/asset`;
// use dummy base URL string because the URL constructor only accepts absolute URLs. // use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
@ -6726,6 +6728,14 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
// http bearer authentication required // http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration) await setBearerAuthToObject(localVarHeaderParameter, configuration)
if (skip !== undefined) {
localVarQueryParameter['skip'] = skip;
}
if (take !== undefined) {
localVarQueryParameter['take'] = take;
}
if (userId !== undefined) { if (userId !== undefined) {
localVarQueryParameter['userId'] = userId; localVarQueryParameter['userId'] = userId;
} }
@ -6738,16 +6748,18 @@ export const AssetApiAxiosParamCreator = function (configuration?: Configuration
localVarQueryParameter['isArchived'] = isArchived; localVarQueryParameter['isArchived'] = isArchived;
} }
if (skip !== undefined) {
localVarQueryParameter['skip'] = skip;
}
if (updatedAfter !== undefined) { if (updatedAfter !== undefined) {
localVarQueryParameter['updatedAfter'] = (updatedAfter as any instanceof Date) ? localVarQueryParameter['updatedAfter'] = (updatedAfter as any instanceof Date) ?
(updatedAfter as any).toISOString() : (updatedAfter as any).toISOString() :
updatedAfter; updatedAfter;
} }
if (updatedBefore !== undefined) {
localVarQueryParameter['updatedBefore'] = (updatedBefore as any instanceof Date) ?
(updatedBefore as any).toISOString() :
updatedBefore;
}
if (ifNoneMatch != null) { if (ifNoneMatch != null) {
localVarHeaderParameter['if-none-match'] = String(ifNoneMatch); localVarHeaderParameter['if-none-match'] = String(ifNoneMatch);
} }
@ -8066,17 +8078,19 @@ export const AssetApiFp = function(configuration?: Configuration) {
}, },
/** /**
* Get all AssetEntity belong to the user * Get all AssetEntity belong to the user
* @param {number} [skip]
* @param {number} [take]
* @param {string} [userId] * @param {string} [userId]
* @param {boolean} [isFavorite] * @param {boolean} [isFavorite]
* @param {boolean} [isArchived] * @param {boolean} [isArchived]
* @param {number} [skip]
* @param {string} [updatedAfter] * @param {string} [updatedAfter]
* @param {string} [updatedBefore]
* @param {string} [ifNoneMatch] ETag of data already cached on the client * @param {string} [ifNoneMatch] ETag of data already cached on the client
* @param {*} [options] Override http request option. * @param {*} [options] Override http request option.
* @throws {RequiredError} * @throws {RequiredError}
*/ */
async getAllAssets(userId?: string, isFavorite?: boolean, isArchived?: boolean, skip?: number, updatedAfter?: string, ifNoneMatch?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AssetResponseDto>>> { async getAllAssets(skip?: number, take?: number, userId?: string, isFavorite?: boolean, isArchived?: boolean, updatedAfter?: string, updatedBefore?: string, ifNoneMatch?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<AssetResponseDto>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAssets(userId, isFavorite, isArchived, skip, updatedAfter, ifNoneMatch, options); const localVarAxiosArgs = await localVarAxiosParamCreator.getAllAssets(skip, take, userId, isFavorite, isArchived, updatedAfter, updatedBefore, ifNoneMatch, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
}, },
/** /**
@ -8421,7 +8435,7 @@ export const AssetApiFactory = function (configuration?: Configuration, basePath
* @throws {RequiredError} * @throws {RequiredError}
*/ */
getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig): AxiosPromise<Array<AssetResponseDto>> { getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig): AxiosPromise<Array<AssetResponseDto>> {
return localVarFp.getAllAssets(requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.skip, requestParameters.updatedAfter, requestParameters.ifNoneMatch, options).then((request) => request(axios, basePath)); return localVarFp.getAllAssets(requestParameters.skip, requestParameters.take, requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.updatedAfter, requestParameters.updatedBefore, requestParameters.ifNoneMatch, options).then((request) => request(axios, basePath));
}, },
/** /**
* Get a single asset\'s information * Get a single asset\'s information
@ -8719,6 +8733,20 @@ export interface AssetApiDownloadFileRequest {
* @interface AssetApiGetAllAssetsRequest * @interface AssetApiGetAllAssetsRequest
*/ */
export interface AssetApiGetAllAssetsRequest { export interface AssetApiGetAllAssetsRequest {
/**
*
* @type {number}
* @memberof AssetApiGetAllAssets
*/
readonly skip?: number
/**
*
* @type {number}
* @memberof AssetApiGetAllAssets
*/
readonly take?: number
/** /**
* *
* @type {string} * @type {string}
@ -8742,17 +8770,17 @@ export interface AssetApiGetAllAssetsRequest {
/** /**
* *
* @type {number} * @type {string}
* @memberof AssetApiGetAllAssets * @memberof AssetApiGetAllAssets
*/ */
readonly skip?: number readonly updatedAfter?: string
/** /**
* *
* @type {string} * @type {string}
* @memberof AssetApiGetAllAssets * @memberof AssetApiGetAllAssets
*/ */
readonly updatedAfter?: string readonly updatedBefore?: string
/** /**
* ETag of data already cached on the client * ETag of data already cached on the client
@ -9430,7 +9458,7 @@ export class AssetApi extends BaseAPI {
* @memberof AssetApi * @memberof AssetApi
*/ */
public getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig) { public getAllAssets(requestParameters: AssetApiGetAllAssetsRequest = {}, options?: AxiosRequestConfig) {
return AssetApiFp(this.configuration).getAllAssets(requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.skip, requestParameters.updatedAfter, requestParameters.ifNoneMatch, options).then((request) => request(this.axios, this.basePath)); return AssetApiFp(this.configuration).getAllAssets(requestParameters.skip, requestParameters.take, requestParameters.userId, requestParameters.isFavorite, requestParameters.isArchived, requestParameters.updatedAfter, requestParameters.updatedBefore, requestParameters.ifNoneMatch, options).then((request) => request(this.axios, this.basePath));
} }
/** /**