graemedouglas / littled Goto Github PK
View Code? Open in Web Editor NEWA relational database for embedded devices and sensors nodes
License: Apache License 2.0
A relational database for embedded devices and sensors nodes
License: Apache License 2.0
I'm trying this:
#include "../../dbparser/dbparser.h"
#define BYTES_LEN 400
int main(void)
{
char memseg[BYTES_LEN];
db_query_mm_t mm;
db_op_base_t* root;
db_tuple_t tuple;
init_query_mm(&mm, memseg, BYTES_LEN);
parse("CREATE TABLE sensors (id int, temp int);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (1, 221);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (2, 89884);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (3, 112);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (4, 455);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (5, 3313);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (6, 11);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (7, 99996);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (8, 6565);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
parse("INSERT INTO sensors VALUES (9, 6565);", &mm);
init_query_mm(&mm, memseg, BYTES_LEN);
root = parse("SELECT * FROM sensors ORDER BY id DESC;", &mm);
if (root == NULL) {
printf("NULL root\n");
} else {
init_tuple(&tuple, root->header->tuple_size, root->header->num_attr, &mm);
while (next(root, &tuple, &mm) == 1) {
int id = getintbyname(&tuple, "id", root->header);
int sensor_val = getintbyname(&tuple, "temp", root->header);;
printf("sensor val: %i (%i)\n", sensor_val, id);
}
}
return 0;
}
and getting:
sensor val: 221 (1)
sensor val: 89884 (2)
sensor val: 112 (3)
sensor val: 455 (4)
sensor val: 3313 (5)
sensor val: 11 (6)
sensor val: 99996 (7)
sensor val: 6565 (8)
sensor val: 6565 (9)
But I am expecting the results in the opposite order.
void symswapbytes(char *a, char *b, db_int num_bytes)
{
db_int i = 0;
for (; i < num_bytes; ++i)
{
a[i] = a[i] ^ b[i];
b[i] = a[i] ^ b[i];
a[i] = a[i] ^ b[i];
}
}
It's cute to use xor swap, but of course not to swap memory blocks. 6 memory reads, 3 writes - instead of 2 reads, 2 writes.
This one took me a while to track down, but things stopped working when I moved code from Linux to the Cortex M0 nRF51822 BLE chip. I tracked this back to db_qmm_falloc()
and db_qmm_balloc()
. Basically, if something tries to allocate a buffer of a size not a multiple of 4, when the alloc() functions try to write the size
to the beginning of the allocated area, it causes a misaligned memory access:
*((db_int*)(mmp->last_back)) = size;
My quick and dirty workaround is to convert size to the next biggest multiple of four:
db_int blob = size+sizeof(db_int);
if (blob % 4 != 0) {
blob += (4 - (blob % 4));
}
size = blob - sizeof(db_int);
and throw that near the beginning of the alloc() functions.
I have no idea if that actually fixes anything or just masks issues temporarily. I've ran one SELECT
statement that I got to work with that change in there, but haven't done any more than that (I wanted to get this posted so I didn't forget). It's entirely possible that this is the best solution and that all later accesses are safe.
I found delete records does not work, is it not supported yet?
After I insert some data by "INSERT INTO t1 VALUES (3, 'Pear', 17, 1)", I try to use "INSERT INTO t1 VALUES (3, 'Pear', 18, 2)" to update this piece of data. But it doesn't work.
Is there any function like "unique key" to solve this problem?
Could you give me some advice?
Not sure if I'm doing something wrong here but I'm running this code:
#include "../../dbparser/dbparser.h"
int main(void)
{
{
char memseg[1000];
db_query_mm_t mm;
db_op_base_t* root;
db_tuple_t tuple;
init_query_mm(&mm, memseg, 1000);
// DML commands don't produce operators, they just execute.
parse("CREATE TABLE sensors (temp int);", &mm);
parse("INSERT INTO sensors VALUES (221);", &mm);
parse("INSERT INTO sensors VALUES (89884);", &mm);
parse("INSERT INTO sensors VALUES (112);", &mm);
parse("INSERT INTO sensors VALUES (455);", &mm);
root = parse("SELECT * FROM sensors", &mm);
if (root == NULL) {
// Always gets here
printf("NULL root\n");
} else {
init_tuple(&tuple, root->header->tuple_size, root->header->num_attr, &mm);
while (next(root, &tuple, &mm) == 1) {
// Do whatever. Check src/dbobjects/tuple.h for how to extract tuple data.
printf("ok!\n");
}
}
}
return 0;
}
and the select *
returns NULL. If I add another INSERT or remove one INSERT, the SELECT returns correctly.
On the nRF51822 platform I'm compiling for, having printf()
in the code anywhere (even if it is never called) forces the compiler to include some library that also happens to include fclose()
, which then conflicts with my implementation of the filesystem functions. Currently I've commented out
printQuery
printTuple
printRowSeparator
printtoken
and set DB_CTCONF_SETTING_FEATURE_ERROR_MESSAGES
to 0. It would be nice to have a #define
that lets me remove all printf()
s from compiling.
Hello @graemedouglas,
I just want to know if it is possible in any way to remove a row from a table.
Thanks!
Best regards,
Pedro Ribeiro
Currently it's rather unclear how to use library and what you get in results. Building testsuite produces executable of 500K. That's twice as much as sqlite, and leads to obvious question "why waste time on this?" There're lot of database engines, many of which are better documented/known than this. This one tries to promise high level of unbloatedness, so please make it easy for people to behold that (by executing "make example" or otherwise running simple command from README), and include code size figures for a well-known architecture to README (assuming you're interested in people using and contributing to your project, which is hopefully true if it's put on github). Thanks!
We want use LittleD for our database in microcontroller. So we want stable library, if by chance any issue arise than can we expect solution from you?
I used "SELECT * FROM sensors WHERE id = 1;", but it didn't work.
i am trying to compile this code using arm-none-eabi-gcc, and following linking issues i am facing ..
arm-none-eabi-gcc -MM -MF bin/utils/gen_test_relations.d -MP -MT bin/utils/gen_test_relations -Isrc/include -Wall -g -DENABLE_DEBUG src/utils/gen_test_relations.c
arm-none-eabi-gcc -Isrc/include -Wall -g -DENABLE_DEBUG -o bin/utils/gen_test_relations src/utils/gen_test_relations.c bin/lib/relation.o bin/lib/tuple.o bin/lib/db_query_mm.o bin/lib/dbstorage.o bin/lib/compare_tuple.o bin/lib/eet.o bin/lib/scan.o bin/lib/select.o bin/lib/project.o bin/lib/ntjoin.o bin/lib/osijoin.o bin/lib/sort.o bin/lib/aggregate.o bin/lib/db_ops.o bin/lib/dbindex.o bin/lib/query_output.o bin/lib/dblexer.o bin/lib/dbparseexpr.o bin/lib/dbcreate.o bin/lib/dbinsert.o bin/lib/dbparser.o
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-exit.o): In function exit': exit.c:(.text.exit+0x2c): undefined reference to
_exit'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-fstatr.o): In function _fstat_r': fstatr.c:(.text._fstat_r+0x20): undefined reference to
_fstat'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-openr.o): In function _open_r': openr.c:(.text._open_r+0x24): undefined reference to
_open'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-sbrkr.o): In function _sbrk_r': sbrkr.c:(.text._sbrk_r+0x18): undefined reference to
_sbrk'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-unlinkr.o): In function _unlink_r': unlinkr.c:(.text._unlink_r+0x18): undefined reference to
_unlink'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-writer.o): In function _write_r': writer.c:(.text._write_r+0x24): undefined reference to
_write'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-closer.o): In function _close_r': closer.c:(.text._close_r+0x18): undefined reference to
_close'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-isattyr.o): In function _isatty_r': isattyr.c:(.text._isatty_r+0x18): undefined reference to
_isatty'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-lseekr.o): In function _lseek_r': lseekr.c:(.text._lseek_r+0x24): undefined reference to
_lseek'
d:/armtool/bin/../lib/gcc/arm-none-eabi/6.3.1/../../../../arm-none-eabi/lib\libg.a(lib_a-readr.o): In function _read_r': readr.c:(.text._read_r+0x24): undefined reference to
_read'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:256: bin/utils/gen_test_relations] Error 1
Take as an example:
struct clausenode
{
db_uint8 bcode; /**< Binary code data for
clause. */
db_uint8 clause_i; /**< Clause index.
*/
db_int start; /**< Clause start offset.
*/
db_int end; /**< Clause end offset.
*/
db_uint8 terms; /**< Number of terms in clause.
*/
};
This will (on 32-bit platform) waste 2 bytes after clause_i, then 3 bytes after terms. Rather, smaller members should be put towards the end of structure. In that case, only 1 byte will be wasted.
The project looks interesting, but 10 commits over 2 years doesn't give high hopes. Was it just open-sourced recently? Is it still "ongoing research support by ..."? What's working currently, what's not, what's roadmap? All in all, if it's a typical student project being "open-sourced" a year or so after graduation, of the feeling of nostalgia, before former student completely dissolves in real-life (exciting things like paying bills, work, family, little kids), please tell so, to set everyone's expectations right ;-).
Hi, I am working on an original operating system, and I really appreciate that LittleD is one of a few databases that can run on our system. So I want to do some further research on LittleD: add an in-memory model and transform between memory and dist.
Would you give me some advice?
If I re-write some functioni like 'fopen', 'fwrite' used in 'dbstorage' and make them operate a virtual file, is it enough?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.