-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.c
109 lines (104 loc) · 3.28 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <ftw.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "sqlite3.h"
#include "main.h"
#ifndef O_NOATIME
#define O_NOATIME 0
#endif
void check_schema(sqlite3 *);
sqlite3_stmt* stmt = NULL;
sqlite3* db = NULL;
sqlite3* open_db(char mode){
sqlite3 *ret = NULL;
sqlite3_open(DB_FILENAME, &ret);
check_schema(ret);
return ret;
}
void check_schema(sqlite3 *db){
sqlite3_exec(db, SQL_SCHEMA_CHECK, NULL, NULL, NULL);
}
int add_callback(const char* fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
if(typeflag != FTW_F) return 0;
int effective_filelength = sb->st_size;
if(effective_filelength > SQLITE_MAX_LENGTH - 1) effective_filelength = SQLITE_MAX_LENGTH - 1;
int fd = open(fpath, O_RDONLY | O_NOATIME);
char * file_content = (char *) mmap(NULL, effective_filelength, PROT_READ, MAP_SHARED, fd, 0);
sqlite3_reset(stmt);
sqlite3_bind_text(stmt, 1, fpath, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, file_content, effective_filelength, SQLITE_STATIC);
while(sqlite3_step(stmt) != SQLITE_DONE);
munmap((void *) file_content, effective_filelength);
close(fd);
return 0;
}
void add(char *in) {
db = open_db('\0');
sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
sqlite3_prepare(db, "INSERT INTO files (path, content) VALUES (?, ?);", -1, &stmt, NULL);
nftw(in, &add_callback, 10, 0);// traverse folder, and use prepared statement to add all of the folder in one transaction. TODO: insert debug macro for immediate transactions.
sqlite3_finalize(stmt);
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
}
void search(char *in) {
db = open_db('\0');
sqlite3_prepare(db, "SELECT '\n' || path || '\t' || snippet(files, 1, '\033[1m', '\033[0m', '\e[3m$\033[0m', 64) FROM files WHERE files MATCH ? ORDER BY rank;", -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, in, -1, SQLITE_STATIC);
while(sqlite3_step(stmt) == SQLITE_ROW)
printf("%s", sqlite3_column_text(stmt, 0));
sqlite3_finalize(stmt);
return;
}
int remove_callback(const char* fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf) {
if(typeflag != FTW_F) return 0;
sqlite3_reset(stmt);
sqlite3_bind_text(stmt, 1, fpath, -1, SQLITE_STATIC);
while(sqlite3_step(stmt) != SQLITE_DONE);
return 0;
}
void ind3xlite_remove(char *in) {
db = open_db('\0');
sqlite3_exec(db, "BEGIN;", NULL, NULL, NULL);
sqlite3_prepare(db, "DELETE FROM files WHERE path = ?;", -1, &stmt, NULL);
nftw(in, &remove_callback, 10, 0);
sqlite3_finalize(stmt);
sqlite3_exec(db, "COMMIT;", NULL, NULL, NULL);
}
int main(int argc, char* argv[]){
int action = 0;
if(argc < 3){
printf(MSG_NO_ARGS);
return -1;
}else{
if (!strcmp(argv[1], "add")) action = 1;
else if(!strcmp(argv[1], "a")) action = 1;
else if(!strcmp(argv[1], "search")) action = 2;
else if(!strcmp(argv[1], "s")) action = 2;
else if(!strcmp(argv[1], "remove")) action = 2;
else if(!strcmp(argv[1], "r")) action = 2;
switch(action){
case 1:
for (int i = 2; i < argc; i++)
add(argv[i]);
break;
case 2:
for (int i = 2; i < argc; i++)
search(argv[i]);
break;
case 3:
for (int i = 2; i < argc; i++)
ind3xlite_remove(argv[i]);
break;
default:
printf(MSG_NO_ARGS);
return -1;
}
return 0;
}
}