我制作了自己的数据库格式,遗憾的是需要太多的内存,而且它的大小变得可怕而且保养很糟糕。
所以我正在寻找一种方法来将一个对象的数组存储在一个表中。
我猜我需要使用blob,但欢迎所有其他选项。实现blob的简单方法也很有用。
我附上了我的保存代码和相关结构(从我之前的可怕帖子更新)
#include "stdafx.h"
#include <string>
#include <stdio.h>
#include <vector>
#include "sqlite3.h"
using namespace std;
struct PriceEntry{
float cardPrice;
string PriceDate;
int Edition;
int Rarity;
};
struct cardEntry{
string cardName;
long pesize;
long gsize;
vector<PriceEntry> cardPrices;
float vThreshold;
int fav;
};
vector<cardEntry> Cards;
void FillCards(){
int i=0;
int j=0;
char z[32]={0};
for(j=0;j<3;j++){
cardEntry tmpStruct;
sprintf(z, "Card Name: %d" , i);
tmpStruct.cardName=z;
tmpStruct.vThreshold=1.00;
tmpStruct.gsize=0;
tmpStruct.fav=1;
for(i=0;i<3;i++){
PriceEntry ss;
ss.cardPrice=i+1;
ss.Edition=i;
ss.Rarity=i-1;
sprintf(z,"This is struct %d", i);
ss.PriceDate=z;
tmpStruct.cardPrices.push_back(ss);
}
tmpStruct.pesize=tmpStruct.cardPrices.size();
Cards.push_back(tmpStruct);
}
}
int SaveCards(){
// Create an int variable for storing the return code for each call
int retval;
int CardCounter=0;
int PriceEntries=0;
char tmpQuery[256]={0};
int q_cnt = 5,q_size = 256;
sqlite3_stmt *stmt;
sqlite3 *handle;
retval = sqlite3_open("sampledb.sqlite3",&handle);
if(retval)
{
printf("Database connection failed\n");
return -1;
}
printf("Connection successful\n");
//char create_table[100] = "CREATE TABLE IF NOT EXISTS users (uname TEXT PRIMARY KEY,pass TEXT NOT NULL,activated INTEGER)";
char create_table[] = "CREATE TABLE IF NOT EXISTS Cards (CardName TEXT, PriceNum NUMERIC, Threshold NUMERIC, Fav NUMERIC);";
retval = sqlite3_exec(handle,create_table,0,0,0);
printf( "could not prepare statemnt: %s\n", sqlite3_errmsg(handle) );
for(CardCounter=0;CardCounter<Cards.size();CardCounter++){
char Query[512]={0};
for(PriceEntries=0;PriceEntries<Cards[CardCounter].cardPrices.size();PriceEntries++){
//Here is where I need to find out the process of storing the vector of PriceEntry for Cards then I can modify this loop to process the data
}
sprintf(Query,"INSERT INTO Cards VALUES('%s', %d, %f, %d)",
Cards[CardCounter].cardName.c_str(),
Cards[CardCounter].pesize,
Cards[CardCounter].vThreshold,
Cards[CardCounter].fav); //My insert command
retval = sqlite3_exec(handle,Query,0,0,0);
if(retval){
printf( "Could not prepare statement: %s\n", sqlite3_errmsg(handle) );
}
}
// Insert first row and second row
sqlite3_close(handle);
return 0;
}
我尝试使用谷歌搜索,但我的结果还不够。
答案 0 :(得分:3)
这里有两种类型:Cards和PriceEntries。对于每张卡,可以有很多PriceEntries。
您可以将卡存储在一个表中,每行一个卡。但你对如何存储PriceEntries感到困惑,对吧?
您通常在这里做的是具有PriceEntries的第二个表,键入了Cards表的唯一列(或列)。我想CardName对每张卡都是唯一的吗?我们一起去吧。因此,您的PriceEntry表将具有列CardName,后面是PriceEntry信息列。即使CardName列中有重复项,每个PriceEntry也会有一行。
PriceEntry表可能如下所示:
CardName | Some PE value | Some other PE value
Ace | 1 | 1
Ace | 1 | 5
2 | 2 | 3
等等。因此,当您想要找到一张卡的PriceEntries数组时,您可以
select * from PriceEntry where CardName = 'Ace'
从上面的示例数据中你可以得到2行,你可以将其推入数组(如果你愿意的话)。
不需要BLOB!
答案 1 :(得分:0)
这是一个简单的序列化和反序列化系统。 PriceEntry类已经扩展了序列化支持(非常简单)。现在,您只需将PriceEntry(或其中一组)序列化为二进制数据并将其存储在blob列中。稍后,您将获得blob数据,并从中反序列化具有相同值的新PriceEntry。底部给出了如何使用它的一个例子。享受。
#include <iostream>
#include <vector>
#include <string>
#include <cstring> // for memcpy
using std::vector;
using std::string;
// deserialization archive
struct iarchive
{
explicit iarchive(vector<unsigned char> data)
: _data(data)
, _cursor(0)
{}
void read(float& v) { read_var(v); }
void read(int& v) { read_var(v); }
void read(size_t& v) { read_var(v); }
void read(string& v) { read_string(v); }
vector<unsigned char> data() { return _data; }
private:
template <typename T>
void read_var(T& v)
{
// todo: check that the cursor will not be past-the-end after the operation
// read the binary data
std::memcpy(reinterpret_cast<void*>(&v), reinterpret_cast<const void*>(&_data[_cursor]), sizeof(T));
// advance the cursor
_cursor += sizeof(T);
}
inline
void
read_string(string& v)
{
// get the array size
size_t sz;
read_var(sz);
// get alignment padding
size_t padding = sz % 4;
if (padding == 1) padding = 3;
else if (padding == 3) padding = 1;
// todo: check that the cursor will not be past-the-end after the operation
// resize the string
v.resize(sz);
// read the binary data
std::memcpy(reinterpret_cast<void*>(&v[0]), reinterpret_cast<const void*>(&_data[_cursor]), sz);
// advance the cursor
_cursor += sz + padding;
}
vector<unsigned char> _data; // archive data
size_t _cursor; // current position in the data
};
// serialization archive
struct oarchive
{
void write(float v) { write_var(v); }
void write(int v) { write_var(v); }
void write(size_t v) { write_var(v); }
void write(const string& v) { write_string(v); }
vector<unsigned char> data() { return _data; }
private:
template <typename T>
void write_var(const T& v)
{
// record the current data size
size_t s(_data.size());
// enlarge the data
_data.resize(s + sizeof(T));
// store the binary data
std::memcpy(reinterpret_cast<void*>(&_data[s]), reinterpret_cast<const void*>(&v), sizeof(T));
}
void write_string(const string& v)
{
// write the string size
write(v.size());
// get alignment padding
size_t padding = v.size() % 4;
if (padding == 1) padding = 3;
else if (padding == 3) padding = 1;
// record the data size
size_t s(_data.size());
// enlarge the data
_data.resize(s + v.size() + padding);
// store the binary data
std::memcpy(reinterpret_cast<void*>(&_data[s]), reinterpret_cast<const void*>(&v[0]), v.size());
}
vector<unsigned char> _data; /// archive data
};
struct PriceEntry
{
PriceEntry()
{}
PriceEntry(iarchive& in) // <<< deserialization support
{
in.read(cardPrice);
in.read(PriceDate);
in.read(Edition);
in.read(Rarity);
}
void save(oarchive& out) const // <<< serialization support
{
out.write(cardPrice);
out.write(PriceDate);
out.write(Edition);
out.write(Rarity);
}
float cardPrice;
string PriceDate;
int Edition;
int Rarity;
};
int main()
{
// create a PriceEntry
PriceEntry x;
x.cardPrice = 1;
x.PriceDate = "hi";
x.Edition = 3;
x.Rarity = 0;
// serialize it
oarchive out;
x.save(out);
// create a deserializer archive, from serialized data
iarchive in(out.data());
// deserialize a PriceEntry
PriceEntry y(in);
std::cout << y.cardPrice << std::endl;
std::cout << y.PriceDate << std::endl;
std::cout << y.Edition << std::endl;
std::cout << y.Rarity << std::endl;
}