C++ 通过SQLite实现命令行工具
本文介绍了一个基于 C++、SQLite 和 Boost 库的简单交互式数据库操作 Shell。该 Shell 允许用户通过命令行输入执行各种数据库操作,包括添加、删除主机信息,设置主机到特定主机组,以及显示主机和主机组列表。通过调用 SQLite3 库实现数据库连接和操作,以及使用 Boost 库进行字符串解析和格式化。该交互式 Shell 提供了一些基本的命令,使用户能够方便地管理主机信息和组织结构。代码结构清晰,易于理解,可根据需要扩展和定制功能。
数据库的基本使用方法请看《C/C++ 通过SQLiteSDK增删改查》这篇文章,针对如何使用Boost解析命令行参数请看《4.9 C++ Boost 命令行解析库》这篇文章,此处只给出实现代码,如下所示;
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <time.h>
#include "sqlite3.h"
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
sqlite3* open_database(std::string database_name)
{
int ref = -1;
sqlite3 *db = 0;
ref = sqlite3_open(database_name.c_str(), &db);
if (ref == SQLITE_OK)
return db;
return false;
}
bool close_database(sqlite3 *db)
{
int ref = sqlite3_close(db);
if (ref == SQLITE_OK)
return true;
return false;
}
bool exec_sql(sqlite3 *db, char *sql)
{
char *error_code = 0;
int ref = sqlite3_exec(db, sql, 0, 0, &error_code);
if (ref == SQLITE_OK)
{
return true;
}
return false;
}
// 初始化创建表结构
void Init_Database()
{
sqlite3* open_db = open_database("./database.db");
if (open_db != false)
{
std::string sql =
"create table HostDB("
"uid primary key,"
"host_address char(128) not null,"
"host_username char(128) not null,"
"host_password char(128) not null,"
"host_port char(128) not null,"
"host_group char(128) not null default 'DefaultGroup'"
");";
char run_sql[1024] = { 0 };
strcpy(run_sql, sql.c_str());
exec_sql(open_db, run_sql);
}
close_database(open_db);
}
// 增加一条主机记录
void AddHost_DB(sqlite3* open_db, std::string address, std::string username, std::string password, std::string port)
{
std::string format_string = boost::str(boost::format("insert into HostDB(host_address,host_username,host_password,host_port) values('%s','%s','%s','%s');") % address %username %password %port);
char run_sql[2048] = { 0 };
strcpy(run_sql, format_string.c_str());
bool ref = exec_sql(open_db, run_sql);
if (ref == true)
{
std::cout << "[+] 增加主机: " << address << " 完成" << std::endl;
}
}
// 删除特定主机记录
void DeleteHost_DB(sqlite3 *open_db, std::string address)
{
std::string format_string = boost::str(boost::format("delete from HostDB where host_address = '%s';") % address);
char run_sql[2048] = { 0 };
strcpy(run_sql, format_string.c_str());
bool ref = exec_sql(open_db, run_sql);
if (ref == true)
{
std::cout << "[-] 删除主机: " << address << " 完成" << std::endl;
}
}
// 将特定主机加入到特定主机组
void SetHostGroup_DB(sqlite3* open_db, std::string address, std::string group_name)
{
std::string format_string = boost::str(boost::format("update HostDB set host_group='%s' where host_address = '%s';") % group_name %address);
char run_sql[2048] = { 0 };
strcpy(run_sql, format_string.c_str());
bool ref = exec_sql(open_db, run_sql);
if (ref == true)
{
std::cout << "[+] 主机: " << address << " 已加入到: " << group_name << " 组" << std::endl;
}
}
// 输出所有主机组
void ShowHostGroup_DB(sqlite3 *open_db)
{
sqlite3_stmt *stmt = 0;
// std::string format_string = "SELECT distinct(host_group) FROM 'HostDB';";
std::string format_string = "SELECT host_group,count(*) FROM HostDB GROUP BY host_group;";
char run_sql[1024] = { 0 };
strcpy(run_sql, format_string.c_str());
int ref = sqlite3_prepare_v2(open_db, run_sql, -1, &stmt, 0);
if (ref == SQLITE_OK)
{
while (sqlite3_step(stmt) == SQLITE_ROW)
{
const unsigned char *host_group = sqlite3_column_text(stmt, 0);
int host_group_count = sqlite3_column_int(stmt, 1);
std::cout << host_group << " " << host_group_count << std::endl;
}
}
sqlite3_finalize(stmt);
}
// 输出所有主机
void ShowHost_DB(sqlite3 *open_db)
{
sqlite3_stmt *stmt = 0;
std::string format_string = "select * from HostDB;";
char run_sql[1024] = { 0 };
strcpy(run_sql, format_string.c_str());
int ref = sqlite3_prepare_v2(open_db, run_sql, -1, &stmt, 0);
if (ref == SQLITE_OK)
{
while (sqlite3_step(stmt) == SQLITE_ROW)
{
const unsigned char *host_address = sqlite3_column_text(stmt, 1);
const unsigned char *host_username = sqlite3_column_text(stmt, 2);
const unsigned char *host_paddword = sqlite3_column_text(stmt, 3);
const unsigned char *host_port = sqlite3_column_text(stmt, 4);
const unsigned char *host_group = sqlite3_column_text(stmt, 5);
std::cout << host_address << " "
<< host_username << " "
<< host_paddword << " "
<< host_port << " "
<< host_group << std::endl;
}
}
sqlite3_finalize(stmt);
}
// 输出特定主机组中的主机
void ShowGroupHostList(sqlite3 *open_db, std::string group_name)
{
sqlite3_stmt *stmt = 0;
std::string format_string = boost::str(boost::format("select * from HostDB where host_group = '%s';") % group_name);
char run_sql[2048] = { 0 };
strcpy(run_sql, format_string.c_str());
int ref = sqlite3_prepare_v2(open_db, run_sql, -1, &stmt, 0);
if (ref == SQLITE_OK)
{
std::cout << "----------------------------------------------------------" << std::endl;
std::cout << "主机组: " << group_name << std::endl;
std::cout << "----------------------------------------------------------" << std::endl;
while (sqlite3_step(stmt) == SQLITE_ROW)
{
const unsigned char *host_address = sqlite3_column_text(stmt, 1);
const unsigned char *host_username = sqlite3_column_text(stmt, 2);
const unsigned char *host_port = sqlite3_column_text(stmt, 4);
std::cout << host_address << " "
<< host_username << " "
<< host_port << std::endl;
}
}
sqlite3_finalize(stmt);
}
int main(int argc, char const *argv[])
{
sqlite3* open_db = open_database("./database.db");
Init_Database();
std::string command;
while (1)
{
std::cout << "[ LyShark Shell ] # ";
std::getline(std::cin, command);
if (command.length() == 0)
{
continue;
}
else if (command == "help")
{
std::cout << "帮助菜单" << std::endl;
}
else
{
boost::char_separator<char> sep(", --");
typedef boost::tokenizer<boost::char_separator<char>> CustonTokenizer;
CustonTokenizer tok(command, sep);
std::vector<std::string> vecSegTag;
for (CustonTokenizer::iterator beg = tok.begin(); beg != tok.end(); ++beg)
{
vecSegTag.push_back(*beg);
}
if (vecSegTag.size() == 9 && vecSegTag[0] == "AddHost")
{
if (vecSegTag[1] == "address" && vecSegTag[3] == "username" && vecSegTag[5] == "password" && vecSegTag[7] == "port")
{
std::string set_address = vecSegTag[2];
std::string set_username = vecSegTag[4];
std::string set_password = vecSegTag[6];
std::string set_port = vecSegTag[8];
AddHost_DB(open_db, set_address, set_username, set_password, set_port);
}
}
else if (vecSegTag.size() == 3 && vecSegTag[0] == "DeleteHost")
{
if (vecSegTag[1] == "address")
{
std::string set_address = vecSegTag[2];
DeleteHost_DB(open_db, set_address);
}
}
else if (vecSegTag.size() == 5 && vecSegTag[0] == "SetHostGroup")
{
if (vecSegTag[1] == "address" && vecSegTag[3] == "group")
{
std::string set_address = vecSegTag[2];
std::string set_group = vecSegTag[4];
SetHostGroup_DB(open_db, set_address, set_group);
}
}
else if (vecSegTag.size() == 1 && vecSegTag[0] == "ShowHost")
{
std::cout << "-----------------------------------------------------------------------------" << std::endl;
std::cout << "IP地址 " << "用户名 " << "密码 " << "端口号 " << "默认组 " << std::endl;
std::cout << "-----------------------------------------------------------------------------" << std::endl;
ShowHost_DB(open_db);
}
else if (vecSegTag.size() == 1 && vecSegTag[0] == "ShowHostGroup")
{
std::cout << "-----------------------------------------------------------------------------" << std::endl;
std::cout << "主机组名 " << "主机数量 " << std::endl;
std::cout << "-----------------------------------------------------------------------------" << std::endl;
ShowHostGroup_DB(open_db);
}
else if (vecSegTag.size() == 3 && vecSegTag[0] == "ShowGroupHostList")
{
if (vecSegTag[1] == "group")
{
std::string set_group = vecSegTag[2];
ShowGroupHostList(open_db, set_group);
}
}
}
}
close_database(open_db);
return 0;
}
添加主机记录: AddHost --address 192.168.1.1 --username root --password 1233 --port 22

删除主机记录: DeleteHost --address 192.168.1.1

将特定主机设置到主机组: SetHostGroup --address 192.168.1.1 --group WebServer

输出所有主机列表: ShowHost

输出所有主机组: ShowHostGroup

输出特定主机组中的主机: ShowGroupHostList --group DefaultGroup

C++ 通过SQLite实现命令行工具的更多相关文章
- 7.0、Android Studio命令行工具
命令行工具分成SDK工具和平台工具. SDK工具 SDK工具跟随SDK安装包安装并随时更新. Virtual Device 工具 1. Android Virtual Device Manager 提 ...
- 七个用于数据科学(data science)的命令行工具
七个用于数据科学(data science)的命令行工具 数据科学是OSEMN(和 awesome 相同发音),它包括获取(Obtaining).整理(Scrubbing).探索(Exploring) ...
- windows下的命令行工具babun
什么是babun babun是windows上的一个第三方shell,在这个shell上面你可以使用几乎所有linux,unix上面的命令,他几乎可以取代windows的shell.用官方的题目说就是 ...
- 『.NET Core CLI工具文档』(一).NET Core 命令行工具(CLI)
说明:本文是个人翻译文章,由于个人水平有限,有不对的地方请大家帮忙更正. 原文:.NET Core Command Line Tools 翻译:.NET Core命令行工具 什么是 .NET Core ...
- 命令行工具aspnet_regiis.exe实现加密和解密web.config
命令行工具aspnet_regiis.exe,是一个类似于DOS的命令工具,称之为命令解释器.使用命令行工具加密和解密web.config文件中的数据库连接字符串时,只需要简单的语法命令即可. 加密语 ...
- nodejs 编写(添加时间戳)命令行工具 timestamp
Nodejs除了编写服务器端程序还可以编写命令行工具,如gulp.js就是Nodejs编写的. 接下来我们来实现一个添加时间戳的命令: $ timestamp action https://www.n ...
- 如何用Node编写命令行工具
0. 命令行工具 当全局安装模块之后,我们可以在控制台下执行指定的命令来运行操作,如果npm一样.我把这样的模块称之为命令行工具模块(如理解有偏颇,欢迎指正) 1.用Node编写命令行工具 在Node ...
- Orchard中的命令行工具
在Orchard中提供了一个命令行工具,我们可以使用这个命令行工具创建用户.创建博客.生成代码.配置网站.打包模块等.并且这个命令行工具是可以扩充的,只要我们在自己开发的模块中创建一个Command类 ...
- Linux 性能监控之命令行工具
引言 对于系统和网络管理员来说每天监控和调试Linux系统的性能问题是一项繁重的工作.这些命令行工具可以在各种Linux系统下使用,可以用于监控和查找产生性能问题的原因.这个命令行工具列表提供了足够的 ...
- 命令行工具解析Crash文件,dSYM文件进行符号化
备份 文/爱掏蜂窝的熊(简书作者)原文链接:http://www.jianshu.com/p/0b6f5148dab8著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 序 在日常开发 ...
随机推荐
- 使用 BLIP-2 零样本“图生文”
本文将介绍来自 Salesforce 研究院的 BLIP-2 模型,它支持一整套最先进的视觉语言模型,且已集成入 Transformers. 我们将向你展示如何将其用于图像字幕生成.有提示图像字幕生成 ...
- SE54视图簇
一.创建关联表 头表 行表 设置行表的外键 创建两张表的表维护生成器,此处不再展开 二.SE54视图簇 激活上述 三.创建事务代码维护 四.效果展示 定期更文,欢迎关注 TRANSLATE with ...
- 什么是「滑动窗口算法」(sliding window algorithm),有哪些应用场景?
今天是算法数据结构专题的第2篇文章,我们一起来学习一下「滑动窗口算法」. 前言 最近刷到leetCode里面的一道算法题,里面有涉及到Sliding windowing算法,因此写一篇文章稍微总结一下 ...
- Codeforces Round #623 (Div. 2) A~D题,D题multiset使用
比赛链接:Here 1315A. Dead Pixel 签到题, 比较四个值 max(max(x, a - 1 - x) * b, a * max(y, b - 1 - y)) 1315B. Home ...
- JVM 性能调优 及 为什么要减少 Full GC
本文为博主原创,未经允许不得转载: 系统上线压测,需要了解系统的瓶颈以及吞吐量,并根据压测数据进行对应的优化. 对压测进行 JVM 性能优化,有两条思路: 第一种情况 : 使用压测工具 jmeter ...
- 安卓系统如何使用谷歌框架下的app?
1.问题 安卓系统从理论上无法使用谷歌框架下的应用(比如像GMail,YouTube,Google play等等),会导致一些麻烦(闪退,卡在登陆界面等等) 注意:使用前提是会魔法,否则请绕道 2.解 ...
- 【Kafka系列】(一)Kafka入门
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 系列文章地址 Kafka是什么? 一句话概括:Apache K ...
- Net Core中使用EF Core连接Mysql数据库
Entity Framework Core的前身是微软提供并主推的ORM框架,简称EF,其底层是对ADO.NET的封装.EF支持SQLServer.MYSQL.Oracle.Sqlite等所有主流数据 ...
- [转帖]JVM中年轻代里的对象什么情况下进入老年代?以及老年代垃圾回收算法-标记整理算法
1.躲过15次GC之后进入老年代 系统刚启动时,创建的各种各样的对象,都是分配在年轻代里. 随着慢慢系统跑着跑着,年轻代满了,就会出发Minor GC ,可能1%的少量存活对像转移到空着的Surviv ...
- nexus的简单安装与使用
nexus的简单安装与使用 文件下载 官网上面下载文件比较麻烦, 得科学一些 https://www.sonatype.com/download-oss-sonatype 选择oss 开源版进行下载 ...