Accept random seed from UI for random sorting (#328)

This commit is contained in:
WithoutPants
2020-01-25 14:35:21 +11:00
committed by Leopere
parent c83eb098bc
commit 3d3f8877de
2 changed files with 59 additions and 7 deletions

View File

@@ -93,6 +93,8 @@ func getSort(sort string, direction string, tableName string) string {
direction = "ASC"
}
const randomSeedPrefix = "random_"
if strings.Contains(sort, "_count") {
var relationTableName = strings.Split(sort, "_")[0] // TODO: pluralize?
colName := getColumn(relationTableName, "id")
@@ -100,12 +102,18 @@ func getSort(sort string, direction string, tableName string) string {
} else if strings.Compare(sort, "filesize") == 0 {
colName := getColumn(tableName, "size")
return " ORDER BY cast(" + colName + " as integer) " + direction
} else if strings.HasPrefix(sort, randomSeedPrefix) {
// seed as a parameter from the UI
// turn the provided seed into a float
seedStr := "0." + sort[len(randomSeedPrefix):]
seed, err := strconv.ParseFloat(seedStr, 32)
if err != nil {
// fallback to default seed
seed = randomSortFloat
}
return getRandomSort(tableName, direction, seed)
} else if strings.Compare(sort, "random") == 0 {
// https://stackoverflow.com/a/24511461
// TODO seed as a parameter from the UI
colName := getColumn(tableName, "id")
randomSortString := strconv.FormatFloat(randomSortFloat, 'f', 16, 32)
return " ORDER BY " + "(substr(" + colName + " * " + randomSortString + ", length(" + colName + ") + 2))" + " " + direction
return getRandomSort(tableName, direction, randomSortFloat)
} else {
colName := getColumn(tableName, sort)
var additional string
@@ -122,6 +130,13 @@ func getSort(sort string, direction string, tableName string) string {
}
}
func getRandomSort(tableName string, direction string, seed float64) string {
// https://stackoverflow.com/a/24511461
colName := getColumn(tableName, "id")
randomSortString := strconv.FormatFloat(seed, 'f', 16, 32)
return " ORDER BY " + "(substr(" + colName + " * " + randomSortString + ", length(" + colName + ") + 2))" + " " + direction
}
func getSearch(columns []string, q string) string {
// TODO - susceptible to SQL injection
var likeClauses []string

View File

@@ -46,6 +46,7 @@ export class ListFilterModel {
public criterionOptions: ICriterionOption[] = [];
public criteria: Array<Criterion<any, any>> = [];
public totalCount: number = 0;
public randomSeed: number = -1;
private static createCriterionOption(criterion: CriterionType) {
return new CriterionOption(Criterion.getLabel(criterion), criterion);
@@ -153,6 +154,19 @@ export class ListFilterModel {
const params = rawParms as IQueryParameters;
if (params.sortby !== undefined) {
this.sortBy = params.sortby;
// parse the random seed if provided
const randomPrefix = "random_";
if (this.sortBy && this.sortBy.startsWith(randomPrefix)) {
let seedStr = this.sortBy.substring(randomPrefix.length);
this.sortBy = "random";
try {
this.randomSeed = Number.parseInt(seedStr);
} catch (err) {
// ignore
}
}
}
if (params.sortdir === "asc" || params.sortdir === "desc") {
this.sortDirection = params.sortdir;
@@ -187,6 +201,28 @@ export class ListFilterModel {
}
}
private setRandomSeed() {
if (this.sortBy == "random") {
// #321 - set the random seed if it is not set
if (this.randomSeed == -1) {
// generate 8-digit seed
this.randomSeed = Math.floor(Math.random() * Math.pow(10, 8));
}
} else {
this.randomSeed = -1;
}
}
private getSortBy(): string | undefined {
this.setRandomSeed();
if (this.sortBy == "random") {
return this.sortBy + "_" + this.randomSeed.toString();
}
return this.sortBy;
}
public makeQueryParameters(): string {
const encodedCriteria: string[] = [];
this.criteria.forEach((criterion) => {
@@ -198,8 +234,9 @@ export class ListFilterModel {
encodedCriteria.push(jsonCriterion);
});
const result = {
sortby: this.sortBy,
sortby: this.getSortBy(),
sortdir: this.sortDirection,
disp: this.displayMode,
q: this.searchTerm,
@@ -216,7 +253,7 @@ export class ListFilterModel {
q: this.searchTerm,
page: this.currentPage,
per_page: this.itemsPerPage,
sort: this.sortBy,
sort: this.getSortBy(),
direction: this.sortDirection === "asc" ? SortDirectionEnum.Asc : SortDirectionEnum.Desc,
};
}