Импортируйте несколько файлов, используя пути, хранящиеся в переменных, в таблицы SQLite в C - PullRequest
0 голосов
/ 24 октября 2018

У меня есть следующий код:

char const* const fileName = argv[1]; 
FILE* file = fopen("/home/tariq/Desktop/domainlist.txt", "r"); 
  char path[256] ;
  char subpath[128];

  while (fgets(path, sizeof(path), file)) {
        if (fscanf(file,"%s" ,path)==1){
            memcpy(subpath, &path[23], 30);
            subpath[strlen(subpath)-8] = '\0';
          printf("Path %s ***** SubPath %s\n", path, subpath);

        }
  }

Как вы можете видеть, while выполняет цикл в файле domainlist.txt (который содержит список других текстовых файлов).в переменной path я сохраняю каждый путь из domainlist.txt, а в переменной subpath я сохраняю текст из исходного путиМой вопрос заключается в том, что я хочу (вместо строки printf) создать таблицу SQLite с именем из переменной subpath и импортировать данные из файла по пути переменной.База данных SQLite уже создана, и соединение открыто, я просто хочу создать таблицы и импортировать в них данные.Я пытался использовать termql, но все, что я мог сделать, - это создать отдельную базу данных из каждого файла, который мне не нужен, мне нужна одна БД, но разные таблицы.

Я надеюсь, что смогу правильно описать свой случай.

Спасибо

РЕДАКТИРОВАТЬ

Содержимое файлов, добавляемых в таблицы БД, представляет собой просто список URL-адресов.Пример ниже:

файл (domainlist.txt) содержит список путей,

Пример пути: путь (который будет в переменной пути): / home / tariq / Desktop/BL/ads/domains.txt

Переменная subpath (которую я хочу назвать именем таблицы): ads

Содержимое файла "domains.txt" в указанном выше пути является просто спискомURL.

1 Ответ

0 голосов
/ 25 октября 2018

Предполагая, что вы еще не заработали, просмотр кода в вашем вопросе заставляет меня подозревать, что вы еще не настолько сильны в C, потому что есть некоторые странные моменты, которые на самом деле не имеют никакого смысла (ПочемуВы читаете строку с fgets(), а затем сразу же используете fscanf() для чтения одного слова в ту же переменную, в которую вы только что прочитали строку? Особенно, когда ваш ввод имеет одно имя файла на строку? И что memcpy () будетсломаться, если вы попытаетесь использовать файлы в разных каталогах.)

Вот почему я предложил использовать сценарий оболочки.Со всей вашей информацией в файлах, это будет намного проще, даже если вы свободно говорите на C.

Вот пример, относящийся к bash:

#!/bin/bash
database=test.db
domainsfile=domainlist.txt
coproc sqlite3 -batch -list "$database"
echo "PRAGMA journal_mode = TRUNCATE;" >&${COPROC[1]}
while read filename; do
    d=$(dirname "$filename")
    tablename=$(basename "$d")
    cat >&${COPROC[1]} <<EOF
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "$tablename"(url TEXT);
.import "$filename" "$tablename"
COMMIT;
EOF
done <$domainsfile
echo .quit >&${COPROC[1]}
wait $COPROC_PID

и менее эффективный (потому чтозапускает новый экземпляр оболочки sqlite3 для каждой таблицы вместо использования одного для всех из них), но более универсальную переносимую версию sh:

#!/bin/sh
database=test.db
domainsfile=domainlist.txt
while read filename; do
    d=$(dirname "$filename")
    tablename=$(basename "$d")
    sqlite3 -batch -list "$database" <<EOF
CREATE TABLE IF NOT EXISTS "$tablename"(url TEXT);
.import "$filename" "$tablename"
EOF
done <$domainsfile

Однако некоторые подсказки для версии C:

Для каждого имени файла в domainlist.txt извлеките часть имени таблицы (было бы полезно использовать функции POSIX dirname() и basename()).Затем создайте таблицу с чем-то вроде:

char *errmsg;
char *table_stmt = sqlite3_mprintf("CREATE TABLE \"%s\"(url TEXT);", tablename);
if (sqlite3_exec(db, table_stmt, NULL, NULL, &errmsg) != SQLITE_OK) {
  // Error handling
}
sqlite3_free(table_stmt);

и импортируйте содержимое текущего файла с чем-то вроде:

char *insert_stmt = sqlite3_mprintf("INSERT INTO \"%s\"(url) VALUES (?)", tablename);
sqlite3_stmt *stmt;
if (sqlite3_prepare_v2(db, insert_stmt, -1, &stmt, NULL) != SQLITE_OK) {
  // Error handling
}

// Open the current file
// In a loop that reads each line in it:
sqlite3_bind_text(stmt, 1, line, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) != SQLITE_DONE) {
  // Error handling
}
sqlite3_reset(stmt);

// After importing the file:
sqlite3_finalize(stmt);

Возможно, вы захотите обернуть каждый импорт таблицы втранзакция, как в примере с bash, или даже вся эта вещь по соображениям производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...