Skip to content
Extraits de code Groupes Projets
Valider a1186303 rédigé par ‮'s avatar :moyai:
Parcourir les fichiers

update_directory

parent f1f95c50
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Ce commit fait partie de la requête de fusion !2. Les commentaires créés ici seront créés dans le contexte de cette requête de fusion.
#include "update.h"
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SQL_LAST_UPDATE "SELECT last_update FROM misc;"
static void
serror(sqlite3 *db, const char *msg)
{
fprintf(stderr, "%s: %s\n", msg, sqlite3_errmsg(db));
}
static inline void *
mallocf(size_t n)
{
void *res = malloc(n);
if (!res)
fprintf(stderr, "Failed to allocate %ld bytes.\n", n);
return res;
}
static int
directories_and_files(const struct dirent *entry)
{
return entry->d_type == DT_REG || entry->d_type == DT_DIR;
}
static int
update_file(sqlite3 *db, const char *filename, int last_update)
{
// TODO
return 0;
}
static int
update_directory(sqlite3 *db, const char *directory, int last_update)
{
int status_code = -1;
char **queue;
size_t queue_max = 128;
size_t queue_len = 0;
queue = mallocf(queue_max * sizeof(char *));
if (!queue)
goto error;
queue[0] = strdup(directory);
queue_len++;
while (queue_len) {
struct dirent **children;
int n;
char *dir = queue[--queue_len];
n = scandir(dir, &children, directories_and_files, alphasort);
if (n < 0)
fprintf(stderr, "Failed to open '%s': %s.\n", dir, strerror(errno));
for (int i = 0; i < n; i++) {
size_t dirlen = strlen(dir);
char *child = mallocf(dirlen + 258); // child length (256) + null byte + slash
if (!child)
goto error;
strcpy(child, dir);
child[dirlen] = '/';
strcpy(child + dirlen + 1, children[i]->d_name);
if (children[i]->d_type == DT_REG) {
update_file(db, child, last_update);
free(child);
} else {
queue[queue_len++] = child;
}
}
}
status_code = 0;
error:
for (size_t i = 0; i < queue_len; i++)
free(queue[i]);
free(queue);
return status_code;
}
int
lektor_db_update(sqlite3 *db, const char *directory)
{
if (sqlite3_exec(db, "BEGIN TRANSACTION;", 0, 0, 0) != SQLITE_OK) {
serror(db, "Failed to start transaction");
return -1;
}
sqlite3_stmt *stmt = 0;
int last_update = 0;
if (sqlite3_prepare_v2(db, SQL_LAST_UPDATE, -1, &stmt, 0) != SQLITE_OK) {
serror(db, "Failed to get last update time");
goto error;
}
switch (sqlite3_step(stmt)) {
case SQLITE_ROW:
last_update = sqlite3_column_int(stmt, 0);
break;
case SQLITE_DONE:
fprintf(stderr, "Failed to get last update time: table misc is empty");
goto error;
default:
serror(db, "Failed to get last update time");
goto error;
}
if (update_directory(db, directory, last_update) < 0)
goto error;
if (sqlite3_exec(db, "COMMIT;", 0, 0, 0) != SQLITE_OK) {
serror(db, "Failed to commit transaction");
goto error;
}
sqlite3_finalize(stmt);
return 0;
error:
sqlite3_finalize(stmt);
if (sqlite3_exec(db, "ROLLBACK;", 0, 0, 0) != SQLITE_OK)
serror(db, "Failed to rollback transaction, database is corrupted");
return -1;
}
#pragma once
#include <sqlite3.h>
int
lektor_db_update(struct sqlite3 *db, const char *directory);
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter