improved performance -> query time decreased to 1/3

This commit is contained in:
Jean Jacques Avril 2022-02-18 18:07:25 +01:00
parent c91ab95a59
commit e2c7a65e7c
4 changed files with 65 additions and 38 deletions

View File

@ -1,15 +1,29 @@
#include "UserDb.h" #include "UserDb.h"
#define DEBUG
using namespace userdb; using namespace userdb;
UserDb::UserDb() UserDb::UserDb(const char *filename) : filename(filename)
{ {
} }
bool UserDb::remove_user(User &user)
{
return remove_user_by_line(filename, user.line);
}
bool UserDb::add_user(User &user)
{
File db = LittleFS.open(filename, "a");
db.write("\n" + String(user.uid) + ";" + user.first_name + ";" + user.last_name + ";" + user.rfid_uid + ";" + user.user_pin + ";" + user.enabled ? "1" : "0");
db.close();
return true;
}
User UserDb::user_by_pin(String cmp) User UserDb::user_by_pin(String cmp)
{ {
#ifdef DEBUG
Serial.println("Searching for user with pin number " + cmp); Serial.println("Searching for user with pin number " + cmp);
Iterator it = begin_with_filter(&cmp,USERATTRIBUTES::USER_PIN); #endif
Iterator it = begin_with_filter(&cmp, USERATTRIBUTES::USER_PIN);
do do
{ {
User temp = *it; User temp = *it;
@ -21,8 +35,10 @@ User UserDb::user_by_pin(String cmp)
} }
User UserDb::user_by_rfid(String cmp) User UserDb::user_by_rfid(String cmp)
{ {
#ifdef DEBUG
Serial.println("Searching for user with rfid " + cmp); Serial.println("Searching for user with rfid " + cmp);
Iterator it = begin_with_filter(&cmp,USERATTRIBUTES::RFID_UID); #endif
Iterator it = begin_with_filter(&cmp, USERATTRIBUTES::RFID_UID);
do do
{ {
User temp = *it; User temp = *it;
@ -33,8 +49,11 @@ User UserDb::user_by_rfid(String cmp)
return User{.enabled = false}; return User{.enabled = false};
} }
User UserDb::user_by_uid(unsigned long cmp){ User UserDb::user_by_uid(unsigned long cmp)
{
#ifdef DEBUG
Serial.println("Searching for user with user id " + String(cmp)); Serial.println("Searching for user with user id " + String(cmp));
#endif
Iterator it = begin(); Iterator it = begin();
do do
{ {
@ -48,7 +67,8 @@ User UserDb::user_by_uid(unsigned long cmp){
void UserDb::print_to_serial() void UserDb::print_to_serial()
{ {
Serial.println("Starting UserDB Test Read"); Serial.println("Starting UserDB Test Read");
for(Iterator it = begin(); it.has_next(); ++it){ for (Iterator it = begin(); it.has_next(); ++it)
{
User temp = *it; User temp = *it;
Serial.println(temp.toString()); Serial.println(temp.toString());
} }

View File

@ -21,7 +21,7 @@ namespace userdb
struct User struct User
{ {
// User(unsigned long new_uid): uid(new_uid){} // User(unsigned long new_uid): uid(new_uid){}
unsigned long uid; unsigned long uid = -1;
uint32_t line; uint32_t line;
mutable String first_name; mutable String first_name;
mutable String last_name; mutable String last_name;
@ -32,22 +32,24 @@ namespace userdb
bool operator==(const User &o) const { return uid == o.uid; } bool operator==(const User &o) const { return uid == o.uid; }
String toString() String toString()
{ {
return "ID: " + String(uid) + " Name: " + last_name + " " + first_name + " Enabled: " + (enabled ? "Yes" : "No"); return "ID: " + String(uid) + " Name: " + last_name + " " + first_name + " Enabled: " + (enabled ? "Yes" : "No") + " LineNo.: " + String(line) + "[RFID/PIN]" + rfid_uid + "//" + user_pin;
} }
}; };
class UserDb class UserDb
{ {
private: private:
const char *filename;
public: public:
UserDb(); UserDb(const char *filename);
void print_to_serial(); void print_to_serial();
void PrintAll(); void PrintAll();
// User find_user(); // User find_user();
User user_by_pin(String); User user_by_pin(String);
User user_by_rfid(String); User user_by_rfid(String);
User user_by_uid(unsigned long); User user_by_uid(unsigned long);
static User read_csv_line(String &instring, uint32_t line, String *match, USERATTRIBUTES attr) inline User read_csv_line(String &instring, uint32_t &line, String *match, USERATTRIBUTES attr)
{ {
int locations[5]; int locations[5];
int location_index = 0; int location_index = 0;
@ -87,33 +89,26 @@ namespace userdb
res.line = line; res.line = line;
return res; return res;
} }
static User read_csv_line(String &instring, uint32_t line) static inline User read_csv_line(File &instream, uint32_t &line, String *match, USERATTRIBUTES attr)
{ {
int locations[5];
int location_index = 0;
int str_length = instring.length() - 1;
for (int i = 0; i < str_length; i++)
{
if (instring.charAt(i) == ';')
{
locations[location_index] = i;
location_index++;
}
}
User res; User res;
res.rfid_uid = instring.substring(locations[2] + 1, locations[3]); String uid = instream.readStringUntil(';');
res.user_pin = instring.substring(locations[3] + 1, locations[4]); if (attr == USER_ID && !uid.equals(*match))
res.uid = instring.substring(0, locations[0]).toInt(); return res;
res.first_name = instring.substring(locations[0] + 1, locations[1]); res.uid = uid.toInt();
res.last_name = instring.substring(locations[1] + 1, locations[2]); res.first_name = instream.readStringUntil(';');
res.enabled = instring.charAt(locations[4] + 1) == '1' ? true : false; res.last_name = instream.readStringUntil(';');
res.rfid_uid = instream.readStringUntil(';');
if (attr == RFID_UID && !res.rfid_uid.equals(*match))
return res;
res.user_pin = instream.readStringUntil(';');
if (attr == USER_PIN && !res.user_pin.equals(*match))
return res;
res.enabled = instream.read() == '1' ? true : false;
res.line = line; res.line = line;
return res; return res;
} }
static bool remove_user(User &user) bool remove_user(User &user);
{
return remove_user_by_line("userdb.csv", user.line);
}
static bool remove_user_by_line(const char *file, uint32_t line) static bool remove_user_by_line(const char *file, uint32_t line)
{ {
const char *temp_file = ".tmp.csv"; const char *temp_file = ".tmp.csv";
@ -146,6 +141,7 @@ namespace userdb
LittleFS.rename(temp_file, file); LittleFS.rename(temp_file, file);
return false; return false;
} }
bool add_user(User &user);
struct Iterator struct Iterator
{ {
using iterator_category = std::input_iterator_tag; using iterator_category = std::input_iterator_tag;
@ -159,10 +155,12 @@ namespace userdb
} }
Iterator(File data, String *m, USERATTRIBUTES attr) : db_file(data), filter_attr(attr), match(m) Iterator(File data, String *m, USERATTRIBUTES attr) : db_file(data), filter_attr(attr), match(m)
{ {
#ifdef DEBUG
if (filter_attr == NONE) if (filter_attr == NONE)
Serial.println("Started user iterator with "); Serial.println("Started user iterator with ");
else else
Serial.println("Started filtered user iterator with " + String(filter_attr) + " query: " + *match); Serial.println("Started filtered user iterator with " + String(filter_attr) + " query: " + *match);
#endif
if (!data) if (!data)
{ {
@ -196,9 +194,18 @@ namespace userdb
{ {
if (db_file.available()) if (db_file.available())
{ {
String temp = db_file.readStringUntil('\n'); // String temp = db_file.readStringUntil('\n');
current = read_csv_line(temp, line, match, filter_attr); // current = read_csv_line(temp, line, match, filter_attr);
line++; // line++;
current = read_csv_line(db_file, line, match, filter_attr);
while (db_file.available())
{
if (db_file.read() == '\n')
{
++line;
break;
}
}
} }
else else
{ {

View File

@ -1,4 +1,4 @@
//#define DEBUG
#include <Arduino.h> #include <Arduino.h>
#include <Wire.h> #include <Wire.h>
#include "Keyboard.h" #include "Keyboard.h"
@ -11,7 +11,7 @@
#include "Persistence.h" #include "Persistence.h"
// File persistence // File persistence
Persistence persistence; Persistence persistence;
userdb::UserDb userdatabase; userdb::UserDb userdatabase("userdb.csv");
// Rfid // Rfid
Rfid rfid; Rfid rfid;
// i2C Bus // i2C Bus