Transplantation and application of embedded Linux sqlite3

summary

sqlite3 is a small database with less code and less memory. It is written in C, so it is naturally suitable for embedded systems, especially embedded linux. It is quite supported. sqlite3 can run directly through the shell, but this is only limited to testing. In actual project programming, we still use the C/C + + interface function provided by sqlite3, That is, the API interface.

sqlite3 migration

Download C source code from sqlite official website: https://www.sqlite.org/download.html

Unzip the package: tar -zxvf sqlite-autoconf-3360000.tar.gz
Run the configuration file:. / configure -- host = arm linux -- prefix = / work / SRC_ packages/sqlite-autoconf-3071401/dist-sqlite3
– host: Specifies the cross compilation tool, which is consistent with the compiler for compiling Linux
– prefix: Specifies the installation directory where the files generated after compilation are placed. They must be absolute paths
Compile: execute make and then make install
After compilation, the dist SQLite3 folder is generated in the source directory

Copy / dist-sqlite3/bin/sqlite3 to the / bin directory of the development board, and execute chmod 777 sqlite3.
Copy all files of / dist SQLite3 / lib / to the / lib directory of the development board.
Enter "sqlite3" at the terminal to enter sqlite3.

sqlite3 common commands

Enter SQLite3 command terminal: #sqlite3 test.db
Get point command list: SQLite >. Help
Exit sqlite3 operation: SQLite >. Exit or SQLite >. Quit
Open or create the database: SQLite >. Open test.db
View database file information: SQLite >. Database
Create table: CREATE TABLE statement;
View all tables: SQLite >. Tables
View the complete information of all tables: SQLite >. Schema
Drop table: DROP TABLE statement
Add a new data row to a table: INSERT INTO statement
Getting data from database tables: SELECT statement
List the configuration of the current display format: SQLite >. Show
Open header for setting display format: SQLite >. Header on
Setting the display format: SQLite >. Width 2
Example:

# sqlite3 
SQLite version 3.36.0 2021-06-18 18:36:39
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> .open test.db
sqlite> .databases
main: /backup0/test.db r/w
sqlite> create table demo (id int,name char,age int);
sqlite> .tables                                  
demo
sqlite> .schema
CREATE TABLE demo (id int,name char,age int);
sqlite> insert into demo values(100,'WangWu',23);
sqlite> insert into demo values(101,'Tommm',25);
sqlite> .header on
sqlite> .mode column
sqlite> select * from demo;
id   name    age
---  ------  ---
100  WangWu  23 
101  Tommm   25 
sqlite> .exit
#

sqlite3 API usage

Open database

int sqlite3_ Open (file name, SQLite3 * *);

close database

int sqlite3_close(sqlite3 *);

Execute sql statement

int sqlite3_exec(sqlite3*,const char sql,sqlite3_callback,void,char **errmsg );

query data base

int sqlite3_get_table(sqlite3*,const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg);

sqlite3 programming example

Implementation idea:

  • Open the database and execute sqlite3_open;
  • Create database tables and use sqlite3_exec executes the create table statement;
  • Execute insert, delete, query and exit operations according to the input instructions;
#include <stdio.h>
#include <stdlib.h>
#include <sqlite3.h>
#include <string.h>
#include <time.h>
#include <strings.h>

#define DATABASE "fru.db"
typedef struct{
	char time[20];
	char name[16];
	float cost;//cost
	float price;//price
	char in_out[5];//Incoming in, outgoing out
	float number;//Trading volume
	float money;//Transaction amount (cost or selling price * transaction volume)
	float total;//Total inventory
}fruit_t;

void operate_table_cmd_menu()
{
	puts("/******************************************/");
	puts("*operate table cmd menu:");
	printf("*1:insert 2:delete 3:query 4:update 5:quite \n");
	puts("/******************************************/");
	printf("Please input cmd:");
}

const char *get_local_time(char *time_str);
fruit_t *get_last_row(sqlite3 *db,fruit_t *fruit);
int query_callback(void *para, int f_num, char **f_value, char **f_name);
int do_insert_sqlite3(sqlite3 * db);
int do_delete_sqlite3(sqlite3 * db);
int do_query_sqlite3(sqlite3 * db);
void get_columns_name(sqlite3 * db);//Get field name
int do_update_sqlite3(sqlite3 * db);

int main(int argc, const char *argv[])
{
	sqlite3 * db;
	char *errmsg;
	int cmd;
	char sql[128]={};

	//Open sqlite3 database
	if(sqlite3_open(DATABASE,&db) != SQLITE_OK)
	{
		printf("%s\n",sqlite3_errmsg(db));
		exit(-1);
	}
	else
	{
		printf("open %s success.\n",DATABASE);
	}

	//Create a table in the database, set the ID as the primary key value and set it as a self increasing field (ensure the uniqueness of the field)
	sprintf(sql,"create table fru(time char,name char,cost Integer,price Integer,in_out char,number Integer,money Integer,total Integer);");
	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK)
	{
		printf("%s\n",errmsg);
	}
	else
	{
		printf("create or open table success.\n");
	}

	while(1)
	{
		operate_table_cmd_menu();
		while(scanf("%d",&cmd) == 0)
		{
			getchar();
			operate_table_cmd_menu();
		}
		getchar();

		switch(cmd)
		{
			case 1:
				do_insert_sqlite3(db);
				break;
			case 2:
				do_delete_sqlite3(db);
				break;
			case 3:
				do_query_sqlite3(db);
				break;
			case 4:
				do_update_sqlite3(db);
				break;
			case 5:
				sqlite3_close(db);
				exit(0);
			default:
				printf("Error cmd.\n");
		}
	
	}
	return 0;
}

const char *get_local_time(char *time_str)
{
	time_t tim_t;
	struct tm loc_t;

	time(&tim_t);

	loc_t = *localtime(&tim_t);

	sprintf(time_str,"%04d-%d-%02d %02d:%02d:%02d",loc_t.tm_year+1900,loc_t.tm_mon+1,loc_t.tm_mday,loc_t.tm_hour,loc_t.tm_min,loc_t.tm_sec);

	return time_str;
}

fruit_t *get_last_row(sqlite3 *db,fruit_t *fruit)
{
	char **resultp;
	int nrow;
	int ncolumn;
	char sql[128];
	int index_base;
	char *errmsg;

	sprintf(sql,"select * from fru where name='%s';",fruit->name);

	sqlite3_get_table(db,sql,&resultp,&nrow,&ncolumn,&errmsg);
	
	if(nrow == 0)
	{
		return NULL;
	}
	else
	{
		index_base = (nrow)*(ncolumn);
		fruit->cost = atof(resultp[index_base+2]);
		fruit->price = atof(resultp[index_base+3]);
		fruit->total = atof(resultp[index_base+7]);
	}
	return fruit;
}
int do_insert_sqlite3(sqlite3 * db)
{
	fruit_t fruit;
	char sql[128];
	char *errmsg;
	char type[10];

	bzero(&fruit,sizeof(fruit));

	get_local_time(fruit.time);

	printf("input fruit name:");
	scanf("%s",fruit.name);
	getchar();


	if(get_last_row(db,&fruit) != NULL)//This fruit has been recorded in the system
	{
		puts("*************************************");	
		printf("%s cost:%.2f price:%.2f\n",fruit.name,fruit.cost,fruit.price);
		puts("*************************************");	
		printf("if you change it[y|n]:");

		scanf("%s",type);
		getchar();

		if(strncasecmp(type,"y",strlen("y")) == 0)
		{
		char value[20];
			printf("change cost:%.2f of %s [cost|n]:",fruit.cost,fruit.name);
			scanf("%s",value);//Enter the cost to modify the cost, and enter n to discard the modification
			getchar();
			if(strncasecmp(value,"n",strlen("n")) != 0)
				fruit.cost = atof(value);
		
			printf("change price:%.2f of %s [price|n]:",fruit.price,fruit.name);
			scanf("%s",value);//Enter the unit price to modify the unit price, and enter n to discard the modification
			getchar();
			if(strncasecmp(value,"n",strlen("n")) != 0)
				fruit.price = atof(value);
		}
		printf("Please input the number of %s:",fruit.name);
		scanf("%f",&fruit.number);
		getchar();

		fruit.total = fruit.total +fruit.number;
	}
	else//There are no fruit types in the system
	{
		printf("Please input the cost of %s [cost]:",fruit.name);
		while(scanf("%f",&fruit.cost) == 0)
		{
			getchar();
			printf("Please input the cost of %s [cost]:",fruit.name);
		}
		getchar();
	
		printf("Please input the price of %s [price]:",fruit.name);
		while(scanf("%f",&fruit.price) == 0)
		{
			getchar();
			printf("Please input the price of %s [price]:",fruit.name);
		}
		getchar();
			
		printf("Please input the number of %s:",fruit.name);
		scanf("%f",&fruit.number);
		getchar();

		fruit.total = fruit.number;
	}
	
	sprintf(fruit.in_out,"in");

	fruit.money = fruit.cost * fruit.number;


	sprintf(sql,"insert into fru values('%s','%s',%.4f,%.4f,'%s',%.4f,%.4f,%.4f);",fruit.time,fruit.name,fruit.cost,fruit.price,fruit.in_out,fruit.number,fruit.money,fruit.total);//The value of the auto increment field is passed to NULL

	if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK )
	{
		printf("%s\n",errmsg);
		return -1;
	}
	else
	{
		printf("insert:\n ");

		sprintf(sql,"select * from fru where time='%s';",fruit.time);
		get_columns_name(db);//Get field name
		sqlite3_exec(db,sql,query_callback,NULL,&errmsg);
		printf("done\n");

		return 0;
	}
}
int query_callback(void *para, int f_num, char **f_value, char **f_name)
{

	int i;
	for(i=0;i<f_num;i++)
	{
		if(i == 0)
			printf("\t%-19s ",f_value[i]);
		else
			printf("%-10s ",f_value[i]);
	}
	puts("");
	return 0;
}
void get_columns_name(sqlite3 * db)
{
	char **resultp;
	int nrow;
	int ncolumn;
	char *errmsg;
	int i;

	sqlite3_get_table(db,"select * from fru",&resultp,&nrow,&ncolumn,&errmsg);
	printf("\t%-19s ",resultp[0]);
	for(i=1;i<ncolumn;i++)
	{
		printf("%-10s ",resultp[i]);
	}
	puts("");
}
int do_delete_sqlite3(sqlite3 * db)
{
	fruit_t fruit;
	char sql[128];
	char *errmsg;
	char value[20];

	bzero(&fruit,sizeof(fruit));

	get_local_time(fruit.time);

	printf("input fruit name:");
	scanf("%s",fruit.name);
	getchar();


	if(get_last_row(db,&fruit) != NULL)//There is this fruit in the system
	{
		printf("input the out number of %s:",fruit.name);

		scanf("%s",value);
		getchar();

		if(atof(value) > fruit.total)//The remaining quantity is not enough
		{
			printf("The total number:%.4f of %s is not enough, please stock it.\n",fruit.total,fruit.name);
			return -1;
		}
		else
		{
			fruit.number = atof(value);
			fruit.money = fruit.price * fruit.number;
			fruit.total = fruit.total - fruit.number;
		}
	}
	else//There is no such fruit in the system
	{
		printf("We don't have this fruit:%s. Please stock it.",fruit.name);
		return -1;
	}
	
	sprintf(fruit.in_out,"out");

	printf("are you sure delete number:%.4f of %s[y|n]:",fruit.number,fruit.name);
	scanf("%s",value);
	getchar();

	if(strncasecmp(value,"y",strlen("y")) == 0)
	{
		sprintf(sql,"insert into fru values('%s','%s',%.4f,%.4f,'%s',%.4f,%.4f,%.4f);",fruit.time,fruit.name,fruit.cost,fruit.price,fruit.in_out,fruit.number,fruit.money,fruit.total);//The value of the auto increment field is passed to NULL

		if(sqlite3_exec(db,sql,NULL,NULL,&errmsg) != SQLITE_OK )
		{
			printf("%s\n",errmsg);
			return -1;
		}
		else
		{
			printf("delete done\n ");
			return 0;
		}
	}
	else
	{
		printf("delete cancelled.\n");
		return 0;
	}
}
int do_query_sqlite3(sqlite3 * db)
{
	fruit_t fruit;
	char sql[128];
	char *errmsg;
	char value[96];

	bzero(&fruit,sizeof(fruit));

	puts("*************************************");	
	printf("*Examples of query types:\n");
	puts("*[all | name='apple' | in_out='in']");
	//puts("*[all total | apple total | banana total]");
	puts("*[time<'2018-12-5 17:08:08' | total>90 and total<200]");
	puts("*[name='apple' and in_out='in']");
	puts("*************************************");	

	printf("Pease input query type:");
	scanf("%s",value);
	getchar();

	if(strncasecmp("all",value,strlen(value)) == 0)
		sprintf(sql,"select * from fru;");
	else
		sprintf(sql,"select * from fru where %s;",value);//The value of the auto increment field is passed to NULL

	get_columns_name(db);//Get field name
	if(sqlite3_exec(db,sql,query_callback,NULL,&errmsg) != SQLITE_OK )
	{
		printf("%s\n",errmsg);
		return -1;
	}
	else
	{
		printf("query done\n ");
		return 0;
	}
}
int do_update_sqlite3(sqlite3 * db)
{
	fruit_t fruit;
	char sql[128];
	char *errmsg;
	int type;

	bzero(&fruit,sizeof(fruit));

	get_local_time(fruit.time);

	printf("input fruit name:");
	scanf("%s",fruit.name);
	getchar();


	if(get_last_row(db,&fruit) != NULL)//This fruit has been recorded in the system
	{
		puts("*************************************");	
		printf("%s cost:%.2f price:%.2f\n",fruit.name,fruit.cost,fruit.price);
		puts("*************************************");	
		printf("if you update it[1:yes 2:cancel]:");

		scanf("%d",&type);
		getchar();

		char value[20];
		if(type == 1)
		{
			printf("update cost:%.2f of %s [cost|n]:",fruit.cost,fruit.name);
			scanf("%s",value);//Enter the cost to modify the cost, and enter n to discard the modification
			getchar();
			if(strncasecmp(value,"n",strlen("n")) != 0)
				fruit.cost = atof(value);
			
			printf("update price:%.2f of %s [price|n]:",fruit.price,fruit.name);
			scanf("%s",value);//Enter the unit price to modify the unit price, and enter n to discard the modification
			getchar();
			if(strncasecmp(value,"n",strlen("n")) != 0)
				fruit.price = atof(value);
		}
		else
		{
			printf("update cancelled\n");
			return 0;
		}
		sprintf(fruit.in_out,"update");

		sprintf(sql,"insert into fru values('%s','%s',%.4f,%.4f,'%s',%.4f,%.4f,%.4f);",fruit.time,fruit.name,fruit.cost,fruit.price,fruit.in_out,fruit.number,fruit.money,fruit.total);//The value of the auto increment field is passed to NULL
		if(sqlite3_exec(db,sql,query_callback,NULL,&errmsg) != SQLITE_OK )
		{
			printf("%s\n",errmsg);
			return -1;
		}
		else
		{
			printf("update:\n");
			get_columns_name(db);//Get field name
			sprintf(sql,"select * from fru where time='%s';",fruit.time);
			sqlite3_exec(db,sql,query_callback,NULL,&errmsg);
			printf("update done\n ");
			return 0;
		}
	}
	else//There are no fruit types in the system
	{
		printf("We don't have this fruit:%s. Please stock it.",fruit.name);
	}
		return 0;
}

sqlite3 test verification

Cross compilation:
arm-linux-gcc -I /home/ubuntu/sqlite3/install/include/ -L /home/ubuntu/sqlite3/install/lib/ -o sql testSql.c -lsqlite3 –ldl
-I specifies the path of sqlite3.h,
-L specifies the lib library path of sqlite3.
Copy the generated executable file to the development board and run the test:

Links, sqlite3 rookie tutorial: https://www.runoob.com/sqlite/sqlite-create-table.html
Link, sqlite3 C code example: https://blog.csdn.net/m0_37542524/article/details/84842154

Keywords: Linux Database SQLite

Added by flashroiem on Wed, 06 Oct 2021 19:04:22 +0300