/
VirusVK
/
ServerIT
Обзор
Документация
Войти
/
VirusVK
/
ServerIT
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
armdb/src/query/sort.c
118 строк
4 KB
VirusVK
upload files
13 дек 2025, 14:28
13 дек 2025, 14:28
a626524
Код
Авторство
О чём код?
#include <stdlib.h> #include <string.h> #include <ctype.h> #include "query.h" #include "models.h" /* Компараторы для АРМ */ static int compare_arms_by_inventory_number(const void *a, const void *b) { const ArmRecord *arm1 = (const ArmRecord *)a; const ArmRecord *arm2 = (const ArmRecord *)b; return strcmp(arm1->inventory_number, arm2->inventory_number); } static int compare_arms_by_name(const void *a, const void *b) { const ArmRecord *arm1 = (const ArmRecord *)a; const ArmRecord *arm2 = (const ArmRecord *)b; return strcmp(arm1->name, arm2->name); } static int compare_arms_by_created_at(const void *a, const void *b) { const ArmRecord *arm1 = (const ArmRecord *)a; const ArmRecord *arm2 = (const ArmRecord *)b; if (arm1->created_at.seconds < arm2->created_at.seconds) return -1; if (arm1->created_at.seconds > arm2->created_at.seconds) return 1; if (arm1->created_at.nanoseconds < arm2->created_at.nanoseconds) return -1; if (arm1->created_at.nanoseconds > arm2->created_at.nanoseconds) return 1; return 0; } /* Компараторы для пользователей */ static int compare_users_by_username(const void *a, const void *b) { const UserRecord *user1 = (const UserRecord *)a; const UserRecord *user2 = (const UserRecord *)b; return strcmp(user1->username, user2->username); } static int compare_users_by_full_name(const void *a, const void *b) { const UserRecord *user1 = (const UserRecord *)a; const UserRecord *user2 = (const UserRecord *)b; return strcmp(user1->full_name, user2->full_name); } /* Компараторы для подразделений */ static int compare_departments_by_name(const void *a, const void *b) { const DepartmentRecord *dept1 = (const DepartmentRecord *)a; const DepartmentRecord *dept2 = (const DepartmentRecord *)b; return strcmp(dept1->name, dept2->name); } /* Функция сортировки записей */ void sort_records(void *records, int count, size_t record_size, const char *sort_field, bool ascending) { if (!records || count <= 1 || !sort_field) return; Comparator comparator = NULL; // Выбираем компаратор в зависимости от поля сортировки if (strcmp(sort_field, "inventory_number") == 0) { comparator = compare_arms_by_inventory_number; } else if (strcmp(sort_field, "name") == 0) { comparator = compare_arms_by_name; } else if (strcmp(sort_field, "created_at") == 0) { comparator = compare_arms_by_created_at; } else if (strcmp(sort_field, "username") == 0) { comparator = compare_users_by_username; } else if (strcmp(sort_field, "full_name") == 0) { comparator = compare_users_by_full_name; } else if (strcmp(sort_field, "department_name") == 0) { comparator = compare_departments_by_name; } if (!comparator) return; // Сортируем qsort(records, count, record_size, comparator); // Если нужен обратный порядок if (!ascending) { // Разворачиваем массив uint8_t *bytes = (uint8_t *)records; uint8_t *temp = malloc(record_size); if (!temp) return; for (int i = 0; i < count / 2; i++) { memcpy(temp, bytes + i * record_size, record_size); memcpy(bytes + i * record_size, bytes + (count - 1 - i) * record_size, record_size); memcpy(bytes + (count - 1 - i) * record_size, temp, record_size); } free(temp); } } /* Сортировка с несколькими полями */ typedef struct { const char *field; bool ascending; } SortKey; void sort_records_multi(void *records, int count, size_t record_size, const SortKey *keys, int key_count) { if (!records || count <= 1 || !keys || key_count == 0) return; // TODO: реализовать сортировку по нескольким полям // Для простоты сортируем по первому полю sort_records(records, count, record_size, keys[0].field, keys[0].ascending); }