C++ 通过SQLite实现命令行工具

news2024/11/29 3:39:02

本文介绍了一个基于 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1254039.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零基础学Linux内核:1、Linux源码组织架构

文章目录 前言一、Linux内核的特征二、Linux操作系统结构1.Linux在系统中的位置2.Linux内核的主要子系统3、Linux系统主要数据结构 三、linux内核源码组织1、下载Linux源码2、Linux版本号3、linux源码架构目录讲解 前言 这里将是我们从零开始学习Linux的第一节&#xff0c;这节…

python 基于opencv和face_recognition的人脸识别

python 基于opencv和face_recognition的人脸识别 代码如下&#xff1a; 使用一个photos存放你需要识别的照片&#xff0c;注意一个人一张就行 然后通过下面代码注册用户&#xff0c;之后启动程序&#xff0c;就会调用摄像头进行识别了。 AddPhoto(“发哥”, “./photos/fag…

京东APP在哪里找到如何申请价格保护查看购买商品价格保护情况的记录信息?

京东价格保护是一项优质售后服务&#xff0c;用户在京东购买商品后&#xff0c;如果该商品在保护期内降价&#xff0c;用户可以申请价格保护&#xff0c;京东将补差价或返还京豆。这项服务旨在保障用户权益&#xff0c;让用户在购买商品时更加安心。用户在购买商品后&#xff0…

python-opencv 人脸68点特征点检测

python-opencv 人脸68点特征点检测 不是很难&#xff0c;主要还是掉包&#xff0c;来看一下代码啊&#xff1a; # coding: utf-8 # 导包 import numpy as np import dlib import cv2class face_emotion(object):def __init__(self):# 人脸检测器对象&#xff0c;通过它拿到人…

2024年天津天狮学院专升本食品质量与安全专业《分析化学》考纲

2024年天津天狮学院食品质量与安全专业高职升本入学考试《分析化学》考试大纲 一、考试性质 《分析化学》专业课程考试是天津天狮学院食品质量与安全专业高职升本入学考试 的必考科目之一&#xff0c;其性质是考核学生是否达到了升入本科继续学习的要求而进行的选拔性考试。《…

JSP 条件动作标签之if标签详解

好 上文 JSP JSTL引入依赖并演示基础使用我们导入了 JSTL的JAR 并 演示了 IF标签的基础使用 本文 我们来说说 平时开发的常用标签 这里 我们需要先强调一下 常用标签 操作的全部都是域对象 首先 我们来看 条件动作标签 条件动作标签的特点是 依赖于某些域对象值 控制页面输出…

【机器学习 | 聚类】关于聚类最全评价方法大全,确定不收藏?

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

队列实现栈VS栈实现队列

目录 【1】用队列实现栈 思路分析 ​ 易错总结 Queue.c&Queue.h手撕队列 声明栈MyStack 创建&初始化栈myStackCreate 压栈myStackPush 出栈&返回栈顶元素myStackPop 返回栈顶元素myStackTop 判断栈空否myStackEmpty 释放空间myStackFree MyStack总代码…

【LeetCode:828. 统计子串中的唯一字符 | 贡献法 乘法原理】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

YOLOv5小目标检测层

目录 一、原理 二、yaml配置文件 一、原理 小目标检测层,就是增加一个检测头,增加一层锚框,用来检测输入图像中像素较小的目标 二、yaml配置文件 # YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parameters nc: 3 # number of classes depth_multiple: 0.33 # model…

Matplotlib网格子图_Python数据分析与可视化

Matplotlib网格子图 plt.subplot()绘制子图调整子图之间的间隔plt.subplots创建网格 plt.subplot()绘制子图 若干彼此对齐的行列子图是常见的可视化任务&#xff0c;matplotlib拥有一些可以轻松创建它们的简便方法。最底层且最常用的方法是plt.subplot()。 这个函数在一个网格…

RocketMq 队列(MessageQueue)

RocketMq是阿里出品&#xff08;基于MetaQ&#xff09;的开源中间件&#xff0c;已捐赠给Apache基金会并成为Apache的顶级项目。基于java语言实现&#xff0c;十万级数据吞吐量&#xff0c;ms级处理速度&#xff0c;分布式架构&#xff0c;功能强大&#xff0c;扩展性强。 官方…

C++二分查找:统计点对的数目

本题其它解法 C双指针算法&#xff1a;统计点对的数目 本周推荐阅读 C二分算法&#xff1a;得到子序列的最少操作次数 本文涉及的基础知识点 二分查找算法合集 题目 给你一个无向图&#xff0c;无向图由整数 n &#xff0c;表示图中节点的数目&#xff0c;和 edges 组成…

赢麻了!义乌一个村有5000个网红,有人年收租就300万!

#义乌一村电商年成交额超300亿# ,在中国&#xff0c;电商行业的发展可谓是日新月异&#xff0c;而位于浙江省义乌市的江北下朱村&#xff0c;正是这股潮流的一个典型代表。这个村子&#xff0c;处处弥漫着“直播”的气息&#xff0c;仿佛每个人都在为这个新兴行业助力。 江北下…

openEuler Linux 部署 FineBi

openEuler Linux 部署 FineBi 部署环境 环境版本openEuler Linux22.03MySQL8.0.35JDK1.8FineBi6.0 环境准备 升级系统内核和软件 yum -y updatereboot安装常用工具软件 yum -y install vim tar net-tools 安装MySQL8 将 MySQL Yum 存储库添加到系统的存储库列表中 sudo…

【anaconda】numpy.dot 向量点乘小技巧

假设向量A[1,1], 向量B[2,3]。如果想知道他们的内积就可以输入如下代码: 当然&#xff0c;如果是两个列向量相乘&#xff0c;肯定是不对的 但是如果没有维度也一样可以求得内积&#xff0c;而且结果不会套在列表里

自驾游汽车托运是交智商税吗?

自驾游汽车托运是交智商税吗? 亲爱的小伙伴们 你们有没有遇到过这样的困扰&#xff1a; 自驾游时&#xff0c;车辆的运输问题让你头疼不已? 是选择自己驾驶还是托运呢? 今天&#xff0c;我就来给大家种草一下汽车托运的好处&#xff0c; 让你的自驾游之旅更加轻松愉快! 1️.…

适用于 Mac 和 Windows 的顶级U 盘数据恢复软件

由于意外删除或设备故障而丢失 USB 驱动器中的数据始终是一件令人压力很大的事情&#xff0c;检索该信息的最佳选择是使用优质数据恢复软件。为了让事情变得更容易&#xff0c;我们已经为您完成了所有研究并测试了工具&#xff0c;并且我们列出了最好的 USB 记忆棒恢复软件&…

计算机编程基础教程,中文编程工具下载,编程构件组合按钮

计算机编程基础教程&#xff0c;中文编程工具下载&#xff0c;编程构件组合按钮 给大家分享一款中文编程工具&#xff0c;零基础轻松学编程&#xff0c;不需英语基础&#xff0c;编程工具可下载。 这款工具不但可以连接部分硬件&#xff0c;而且可以开发大型的软件&#xff0c…

Java中的泛型是什么?如何使用泛型类和泛型方法?

Java 中的泛型是一种编程机制&#xff0c;允许你编写可以与多种数据类型一起工作的代码&#xff0c;同时提供编译时类型检查以确保类型的安全性。泛型的主要目的是提高代码的可重用性、类型安全性和程序的整体性能。 泛型类&#xff08;Generic Class&#xff09;: 在泛型类中…