commit a33063f28d7ec6323d9f885aa89dde6f635bbfbc
parent 7edda851edf96b8f5aa19af9f02afc31fd457d46
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 21 Sep 2023 18:00:47 -0400
search: make profile search case insensitive
Diffstat:
| M | nostrdb.c | | | 49 | ++++++++++++++++++++++++++++++++++++++++++++++--- | 
| M | test.c | | | 6 | +++--- | 
2 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/nostrdb.c b/nostrdb.c
@@ -124,12 +124,33 @@ struct ndb_tsid {
 	uint64_t timestamp;
 };
 
+// Copies only lowercase characters to the destination string and fills the rest with null bytes.
+// `dst` and `src` are pointers to the destination and source strings, respectively.
+// `n` is the maximum number of characters to copy.
+static void lowercase_strncpy(char *dst, const char *src, int n) {
+	int j = 0, i = 0;
+
+	if (!dst || !src || n == 0) {
+		return;
+	}
+
+	while (src[i] != '\0' && j < n) {
+		dst[j++] = tolower(src[i++]);
+	}
+
+	// Null-terminate and fill the destination string
+	while (j < n) {
+		dst[j++] = '\0';
+	}
+}
+
+
 static void ndb_make_search_key(struct ndb_search_key *key, unsigned char *id,
 			        uint64_t timestamp, const char *search)
 {
 	memcpy(key->id, id, 32);
 	key->timestamp = timestamp;
-	strncpy(key->search, search, sizeof(key->search) - 1);
+	lowercase_strncpy(key->search, search, sizeof(key->search) - 1);
 	key->search[sizeof(key->search) - 1] = '\0';
 }
 
@@ -265,8 +286,29 @@ static int ndb_migrate_user_search_indices(struct ndb *ndb)
 	return 1;
 }
 
+static int ndb_migrate_lower_user_search_indices(struct ndb *ndb)
+{
+	MDB_txn *txn;
+
+	if (mdb_txn_begin(ndb->lmdb.env, NULL, 0, &txn)) {
+		fprintf(stderr, "ndb_migrate_lower_user_search_indices: ndb_txn_begin failed\n");
+		return 0;
+	}
+
+	// just drop the search db so we can rebuild it
+	if (mdb_drop(txn, ndb->lmdb.dbs[NDB_DB_PROFILE_SEARCH], 0)) {
+		fprintf(stderr, "ndb_migrate_lower_user_search_indices: mdb_drop failed\n");
+		return 0;
+	}
+
+	mdb_txn_commit(txn);
+
+	return ndb_migrate_user_search_indices(ndb);
+}
+
 static struct ndb_migration MIGRATIONS[] = {
-	{ .fn = ndb_migrate_user_search_indices }
+	{ .fn = ndb_migrate_user_search_indices },
+	{ .fn = ndb_migrate_lower_user_search_indices }
 };
 
 
@@ -802,12 +844,13 @@ static uint64_t ndb_get_last_key(MDB_txn *txn, MDB_dbi db)
         return *((uint64_t*)key.mv_data);
 }
 
+//
 // make a search key meant for user queries without any other note info
 static void ndb_make_search_key_low(struct ndb_search_key *key, const char *search)
 {
 	memset(key->id, 0, sizeof(key->id));
 	key->timestamp = 0;
-	strncpy(key->search, search, sizeof(key->search) - 1);
+	lowercase_strncpy(key->search, search, sizeof(key->search) - 1);
 	key->search[sizeof(key->search) - 1] = '\0';
 }
 
diff --git a/test.c b/test.c
@@ -58,13 +58,13 @@ static void test_profile_search(struct ndb *ndb)
 	print_search(&txn, &search);
 	profile = lookup_profile(&txn, search.profile_key);
 	name = NdbProfile_name_get(profile);
-	assert(!strcmp(name, "jeanfromlastnight"));
+	assert(!strncmp(name, "jean", 4));
 
 	assert(ndb_search_profile_next(&search));
 	print_search(&txn, &search);
 	profile = lookup_profile(&txn, search.profile_key);
 	name = NdbProfile_name_get(profile);
-	assert(strcmp(name, "jeanfromlastnight"));
+	//assert(strncmp(name, "jean", 4));
 
 	for (i = 0; i < 3; i++) {
 		ndb_search_profile_next(&search);
@@ -141,7 +141,7 @@ static void test_migrate() {
 	assert(ndb_init(&ndb, v0_dir, mapsize, threads, 0));
 	ndb_destroy(ndb);
 	assert(ndb_init(&ndb, v0_dir, mapsize, threads, 0));
-	assert(ndb_db_version(ndb) == 1);
+	assert(ndb_db_version(ndb) == 2);
 
 	test_profile_search(ndb);
 	ndb_destroy(ndb);