adding mysql code from LuaWebModule

This commit is contained in:
Dario 2019-09-27 21:53:22 +02:00
parent c44656da5c
commit bb4159c701
9 changed files with 682 additions and 3 deletions

View File

@ -0,0 +1,247 @@
#include "MysqlTable.h"
#include <time.h>
#include <mutex>
MysqlTable::MysqlTable(size_t fieldCount)
: mFieldCount(fieldCount), mHeader(nullptr)
{
mHeader = new MysqlTableColumn[fieldCount];
}
MysqlTable::~MysqlTable()
{
if (mHeader) {
delete[] mHeader;
mHeader = nullptr;
}
for (auto it = mRows.begin(); it != mRows.end(); it++) {
for (auto sub_it = (*it)->begin(); sub_it != (*it)->end(); sub_it++) {
delete *sub_it;
}
delete *it;
}
mRows.clear();
}
bool MysqlTable::setHeader(int index, const char* name, MysqlRowType type)
{
if (index < 0 || index >= mFieldCount) {
return false;
}
if (!mHeader) {
return false;
}
mHeader[index].name = name;
mHeader[index].type = type;
return true;
}
bool MysqlTable::addCellToCurrentRow(MysqlTableCell* cell)
{
if (!cell) {
addError(new Error(__FUNCTION__, "zero pointer"));
return false;
}
if (mRows.size() == 0) {
addError(new Error(__FUNCTION__, "row container is empty"));
return false;
}
auto last_row = mRows.back();
auto fieldIndex = last_row->size();
if (fieldIndex >= mFieldCount) {
addError(new Error(__FUNCTION__, "invalid Cell count"));
delete cell;
return false;
}
if (cell->getType() != MYSQL_ROW_NULL && cell->getType() != mHeader[fieldIndex].type) {
addError(new Error(__FUNCTION__, "field type mismatch"));
delete cell;
return false;
}
last_row->push_back(cell);
return true;
}
size_t MysqlTable::getFieldTypeSize(MysqlRowType type)
{
switch (type) {
case MYSQL_ROW_DECIMAL: return sizeof(double);
case MYSQL_ROW_INT: return sizeof(long);
case MYSQL_ROW_LONG: return sizeof(long long);
case MYSQL_ROW_STRING: return sizeof(std::string);
}
return 0;
}
bool MysqlTable::addCellToCurrentRow(MYSQL_BIND* bind)
{
if (!bind) {
addError(new Error(__FUNCTION__, "bind is null"));
return false;
}
/*
SQL Type of Received Value buffer_type Value Output Variable C Type
TINYINT MYSQL_TYPE_TINY signed char
SMALLINT MYSQL_TYPE_SHORT short int
MEDIUMINT MYSQL_TYPE_INT24 int
INT MYSQL_TYPE_LONG int
BIGINT MYSQL_TYPE_LONGLONG long long int
FLOAT MYSQL_TYPE_FLOAT float
DOUBLE MYSQL_TYPE_DOUBLE double
DECIMAL MYSQL_TYPE_NEWDECIMAL char[]
YEAR MYSQL_TYPE_SHORT short int
TIME MYSQL_TYPE_TIME MYSQL_TIME
DATE MYSQL_TYPE_DATE MYSQL_TIME
DATETIME MYSQL_TYPE_DATETIME MYSQL_TIME
TIMESTAMP MYSQL_TYPE_TIMESTAMP MYSQL_TIME
CHAR, BINARY MYSQL_TYPE_STRING char[]
VARCHAR, VARBINARY MYSQL_TYPE_VAR_STRING char[]
TINYBLOB, TINYTEXT MYSQL_TYPE_TINY_BLOB char[]
BLOB, TEXT MYSQL_TYPE_BLOB char[]
MEDIUMBLOB, MEDIUMTEXT MYSQL_TYPE_MEDIUM_BLOB char[]
LONGBLOB, LONGTEXT MYSQL_TYPE_LONG_BLOB char[]
BIT MYSQL_TYPE_BIT char[]
*/
signed char* b = nullptr;
short* s = nullptr;
int* i = nullptr;
long long* ll = nullptr;
float* f = nullptr;
double* d = nullptr;
char* c_str = nullptr;
MYSQL_TIME* time = nullptr;
switch (bind->buffer_type) {
case MYSQL_TYPE_TINY:
b = (signed char*)bind->buffer;
addCellToCurrentRow((long)b[0]);
break;
case MYSQL_TYPE_SHORT:
s = (short*)bind->buffer;
addCellToCurrentRow((long)s[0]);
break;
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONG:
i = (int*)bind->buffer;
addCellToCurrentRow((long)i[0]);
break;
case MYSQL_TYPE_LONGLONG:
ll = (long long*)bind->buffer;
addCellToCurrentRow(ll[0]);
break;
case MYSQL_TYPE_FLOAT:
f = (float*)bind->buffer;
addCellToCurrentRow((double)f[0]);
break;
case MYSQL_TYPE_DOUBLE:
d = (double*)bind->buffer;
addCellToCurrentRow(d[0]);
break;
case MYSQL_TYPE_NEWDECIMAL:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_TINY_BLOB:
case MYSQL_TYPE_BLOB:
case MYSQL_TYPE_MEDIUM_BLOB:
case MYSQL_TYPE_LONG_BLOB:
case MYSQL_TYPE_BIT:
c_str = (char*)bind->buffer;
addCellToCurrentRow(new MysqlTableCellString(c_str, bind->buffer_length));
break;
case MYSQL_TYPE_TIME:
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
time = (MYSQL_TIME*)bind->buffer;
addCellToCurrentRow(new MysqlTableCellDateTime(time[0]));
break;
default:
addError(new ParamError(__FUNCTION__, "unhandled mysql buffer type", bind->buffer_type));
return false;
}
return true;
}
time_t MysqlTable::parseFromMysqlDateTime(const char* mysql_date_time)
{
struct tm * parsedTime;
// used because localtime return an internal pointer, not thread safe
static std::mutex timeMutex;
int year, month, day, hour, minute, second;
// ex: 2009-10-29
if (sscanf(mysql_date_time, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute, &second) != EOF) {
time_t rawTime;
time(&rawTime);
// static, used for every thread
timeMutex.lock();
parsedTime = localtime(&rawTime);
// tm_year is years since 1900
parsedTime->tm_year = year - 1900;
// tm_months is months since january
parsedTime->tm_mon = month - 1;
parsedTime->tm_mday = day;
parsedTime->tm_hour = hour;
parsedTime->tm_min = minute;
parsedTime->tm_sec = second;
rawTime = mktime(parsedTime);
timeMutex.unlock();
return rawTime;
}
return 0;
}
bool MysqlTable::writeAsTableOntoLuaStack(lua_State* l)
{
/*
* http://lua-users.org/wiki/SimpleLuaApiExample
* Ok, now here we go: We pass data to the lua script on the stack.
* That is, we first have to prepare Lua's virtual stack the way we
* want the script to receive it, then ask Lua to run it.
*/
lua_newtable(l); /* We will pass a table */
/*
* To put values into the table, we first push the index, then the
* value, and then call lua_rawset() with the index of the table in the
* stack. Let's see why it's -3: In Lua, the value -1 always refers to
* the top of the stack. When you create the table with lua_newtable(),
* the table gets pushed into the top of the stack. When you push the
* index and then the cell value, the stack looks like:
*
* <- [stack bottom] -- table, index, value [top]
*
* So the -1 will refer to the cell value, thus -3 is used to refer to
* the table itself. Note that lua_rawset() pops the two last elements
* of the stack, so that after it has been called, the table is at the
* top of the stack.
*/
/*
* for (i = 1; i <= 5; i++) {
* lua_pushnumber(L, i); // Push the table index
* lua_pushnumber(L, i * 2); // Push the cell value
* lua_rawset(L, -3); // Stores the pair in the table
*}
*/
for (auto it = mRows.begin(); it != mRows.end(); it++) {
}
return false;
}

174
src/cpp/MySQL/MysqlTable.h Normal file
View File

@ -0,0 +1,174 @@
/*!
*
* \author: einhornimmond
*
* \date: 04.04.19
*
* \brief: Config Basic Structure
*/
#ifndef DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_QUERY_RESULT__H
#define DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_QUERY_RESULT__H
#include <list>
#include <string.h>
#include "../Error/ErrorList.h"
#include "mysql.h"
extern "C" {
#include "../import/lua/luaintf.h"
#include "../import/lua/lauxlib.h"
}
enum MysqlRowType {
MYSQL_ROW_STRING,
MYSQL_ROW_INT, // 32 Bit
MYSQL_ROW_LONG, // 64 Bit
MYSQL_ROW_DECIMAL, // double
MYSQL_ROW_TIMESTAMP,
MYSQL_ROW_DATETIME,
MYSQL_ROW_NULL,
MYSQL_ROW_TYPE_COUNT,
MYSQL_ROW_TYPE_NONE
};
struct MysqlTableColumn
{
MysqlTableColumn()
: type(MYSQL_ROW_NULL), name("null") {}
MysqlRowType type;
std::string name;
};
class MysqlTableCell
{
public:
MysqlTableCell(MysqlRowType type = MYSQL_ROW_NULL) : mType(type) {}
inline bool isString() const { return mType == MYSQL_ROW_STRING; }
inline bool isInt() const { return mType == MYSQL_ROW_INT; }
inline bool isLong() const { return mType == MYSQL_ROW_LONG; }
inline bool isDateTime() const { return mType == MYSQL_ROW_DATETIME; }
inline bool isNull() const { return mType == MYSQL_ROW_NULL; }
inline bool isDecimal() const { return mType == MYSQL_ROW_DECIMAL; }
inline MysqlRowType getType() const { return mType; }
virtual operator const char*() const { return ""; }
virtual operator long() const { return 0; }
virtual operator long long() const { return 0; }
protected:
MysqlRowType mType;
};
class MysqlTableCellString : public MysqlTableCell
{
public:
MysqlTableCellString(const char* content) : MysqlTableCell(MYSQL_ROW_STRING), mContent(content) {}
MysqlTableCellString(const char* content, size_t count) : MysqlTableCell(MYSQL_ROW_STRING), mContent(content, count) {}
virtual operator const char*() const { return mContent.data(); }
protected:
std::string mContent;
};
class MysqlTableCellInt : public MysqlTableCell
{
public:
MysqlTableCellInt(long value) : MysqlTableCell(MYSQL_ROW_INT), mContent(value) {}
virtual operator long() const { return mContent; }
protected:
long mContent;
};
class MysqlTableCellLong : public MysqlTableCell
{
public:
MysqlTableCellLong(const long long& value) : MysqlTableCell(MYSQL_ROW_LONG), mContent(value) {}
virtual operator long long() const { return mContent; }
protected:
long long mContent;
};
class MysqlTableCellTimestamp : public MysqlTableCell
{
public:
MysqlTableCellTimestamp(const time_t& timestamp) : MysqlTableCell(MYSQL_ROW_TIMESTAMP), mTimestamp(timestamp) {}
protected:
time_t mTimestamp;
};
class MysqlTableCellDateTime : public MysqlTableCell
{
public:
MysqlTableCellDateTime(const MYSQL_TIME& mysql_time) : MysqlTableCell(MYSQL_ROW_DATETIME), mMysqlTime(mysql_time) {}
protected:
MYSQL_TIME mMysqlTime;
};
class MysqlTableCellDecimal : public MysqlTableCell
{
public:
MysqlTableCellDecimal(const double& value) : MysqlTableCell(MYSQL_ROW_DECIMAL), mDecimal(value) {}
protected:
double mDecimal;
};
class MysqlTable : public ErrorList
{
public:
MysqlTable(size_t fieldCount);
~MysqlTable();
bool setHeader(int index, const char* name, MysqlRowType type);
inline MysqlRowType getHeaderType(int index) {
if (index > 0 && index < mFieldCount) {
return mHeader[index].type;
}
addError(new ParamError(__FUNCTION__, "invalid field index:", index));
return MYSQL_ROW_TYPE_NONE;
}
inline bool addCellToCurrentRow(long value) { return addCellToCurrentRow(new MysqlTableCellInt(value)); }
inline bool addCellToCurrentRow(const long long& value) { return addCellToCurrentRow(new MysqlTableCellLong(value)); }
inline bool addCellToCurrentRow(const char* string) { return addCellToCurrentRow(new MysqlTableCellString(string)); }
inline bool addCellToCurrentRow(const double& value) { return addCellToCurrentRow(new MysqlTableCellDecimal(value)); }
inline bool addCellToCurrentRowTime(const time_t& time) { return addCellToCurrentRow(new MysqlTableCellTimestamp(time)); }
inline bool addCellToCurrentRow() { return addCellToCurrentRow(new MysqlTableCell); }
bool addCellToCurrentRow(MYSQL_BIND* bind);
//bool copyColumnValues()
//! \brief free memory after not longer using it
bool addCellToCurrentRow(MysqlTableCell* cell);
inline void addRow() { mRows.push_back(new std::list<MysqlTableCell*>); }
inline size_t getRowCount() const { return mRows.size(); }
inline size_t getFieldCount() const { return mFieldCount; }
inline MysqlRowType getRowType(int fieldIndex) const {
if (fieldIndex >= mFieldCount || fieldIndex < 0) return MYSQL_ROW_TYPE_NONE;
return mHeader[fieldIndex].type;
}
/// move to ParseMysqlTable
bool writeAsTableOntoLuaStack(lua_State* l);
static size_t getFieldTypeSize(MysqlRowType type);
static time_t parseFromMysqlDateTime(const char* mysql_date_time);
protected:
size_t mFieldCount;
MysqlTableColumn* mHeader;
std::list<std::list<MysqlTableCell*>*> mRows;
};
#endif //DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_QUERY_RESULT__H

View File

@ -0,0 +1,97 @@
#include "MysqlTableArray.h"
MysqlTableArray::MysqlTableArray(size_t fieldCount, size_t rowCount)
: mFieldCount(fieldCount), mRowCount(rowCount), mHeader(nullptr), mDataBuffer(nullptr)
{
if (fieldCount < 150) {
mHeader = new MysqlTableColumn[fieldCount];
mDataBuffer = (void**)malloc(sizeof(void*) * fieldCount);
memset(mDataBuffer, 0, sizeof(void*) * fieldCount);
}
else {
addError(new Error(__FUNCTION__, "field count greater than 150"));
}
}
MysqlTableArray::~MysqlTableArray()
{
for (int i = 0; i < mFieldCount; i++) {
if (mHeader[i].type == MYSQL_ROW_STRING) {
std::string* strArray = (std::string*)mDataBuffer[i];
delete[] strArray;
}
else {
free(mDataBuffer[i]);
}
}
free(mDataBuffer);
mDataBuffer = nullptr;
delete[] mHeader;
mHeader = nullptr;
}
bool MysqlTableArray::setHeader(int index, const char* name, MysqlRowType type)
{
if (index < 0 || index >= mFieldCount) {
return false;
}
if (!mHeader) {
return false;
}
mHeader[index].name = name;
mHeader[index].type = type;
auto fieldSize = MysqlTable::getFieldTypeSize(type);
if (MYSQL_ROW_STRING == type) {
if (mDataBuffer[index]) delete[] mDataBuffer[index];
mDataBuffer[index] = new std::string[mRowCount];
}
else if (fieldSize) {
if (mDataBuffer[index]) free(mDataBuffer[index]);
mDataBuffer[index] = malloc(fieldSize * mRowCount);
memset(mDataBuffer[index], 0, fieldSize * mRowCount);
}
else {
addError(new ParamError(__FUNCTION__, "wrong type for MysqlTableArray: ", type));
return false;
}
return true;
}
MysqlRowType MysqlTableArray::getRowType(int index)
{
if (index < 0 || index >= mFieldCount) {
addError(new ParamError(__FUNCTION__, "invalid index:", index));
return MYSQL_ROW_TYPE_NONE;
}
if (!mHeader) {
addError(new Error(__FUNCTION__, "error, header not allocated"));
return MYSQL_ROW_TYPE_NONE;
}
return mHeader[index].type;
}
bool MysqlTableArray::checkIndexValid(int fieldIndex, int rowIndex, MysqlRowType type)
{
if (fieldIndex < 0 || fieldIndex >= mFieldCount) {
addError(new ParamError(__FUNCTION__, "error fieldIndex invalid:", fieldIndex));
return false;
}
if (rowIndex < 0 || rowIndex >= mRowCount) {
addError(new ParamError(__FUNCTION__, "error rowIndex invalid:", rowIndex));
return false;
}
if (!mHeader || mHeader[fieldIndex].type != type) {
addError(new ParamError(__FUNCTION__, "error wrong type:", type));
return false;
}
if (!mDataBuffer[fieldIndex]) {
addError(new Error(__FUNCTION__, "no memory allocated"));
return false;
}
return true;
}

View File

@ -0,0 +1,114 @@
/*!
*
* \author: einhornimmond
*
* \date: 11.05.19
*
* \brief: mysql Table as array prepared for prepared statement (cache optimized)
*/
#ifndef DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_MYSQL_TABLE_ARRAY__H
#define DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_MYSQL_TABLE_ARRAY__H
#include <string.h>
#include "../Error/ErrorList.h"
#include "MysqlTable.h"
extern "C" {
#include "../import/lua/luaintf.h"
#include "../import/lua/lauxlib.h"
}
class MysqlTableArray : public ErrorList
{
public:
MysqlTableArray(size_t fieldCount, size_t rowCount);
~MysqlTableArray();
bool setHeader(int index, const char* name, MysqlRowType type);
MysqlRowType getRowType(int index);
inline size_t getRowCount() const { return mRowCount; }
inline size_t getFieldCount() const { return mFieldCount; }
inline MysqlRowType getRowType(int fieldIndex) const {
if (fieldIndex >= mFieldCount || fieldIndex < 0) return MYSQL_ROW_TYPE_NONE;
return mHeader[fieldIndex].type;
}
inline bool setFieldValue(int fieldIndex, int rowIndex, const long& value) {
if (checkIndexValid(fieldIndex, rowIndex, MYSQL_ROW_INT)) {
auto dataArray = (long*)mDataBuffer[fieldIndex];
dataArray[rowIndex] = value;
return true;
}
return false;
}
inline bool setFieldValue(int fieldIndex, int rowIndex, const long long& value) {
if (checkIndexValid(fieldIndex, rowIndex, MYSQL_ROW_LONG)) {
auto dataArray = (long long*)mDataBuffer[fieldIndex];
dataArray[rowIndex] = value;
return true;
}
return false;
}
inline bool setFieldValue(int fieldIndex, int rowIndex, const char* value) {
if (checkIndexValid(fieldIndex, rowIndex, MYSQL_ROW_STRING)) {
auto dataArray = (std::string*)mDataBuffer[fieldIndex];
dataArray[rowIndex] = value;
return true;
}
return false;
}
inline bool setFieldValue(int fieldIndex, int rowIndex, const double& value) {
if (checkIndexValid(fieldIndex, rowIndex, MYSQL_ROW_DECIMAL)) {
auto dataArray = (double*)mDataBuffer[fieldIndex];
dataArray[rowIndex] = value;
return true;
}
return false;
}
inline long* getIntRow(int fieldIndex) {
if (fieldIndex < 0 || fieldIndex >= mFieldCount || mHeader[fieldIndex].type != MYSQL_ROW_INT) {
addError(new ParamError(__FUNCTION__, "invalid field index", fieldIndex));
return nullptr;
}
return (long*)mDataBuffer[fieldIndex];
}
inline long long* getLongRow(int fieldIndex) {
if (fieldIndex < 0 || fieldIndex >= mFieldCount || mHeader[fieldIndex].type != MYSQL_ROW_LONG) {
addError(new ParamError(__FUNCTION__, "invalid field index", fieldIndex));
return nullptr;
}
return (long long*)mDataBuffer[fieldIndex];
}
inline std::string* getStringRow(int fieldIndex) {
if (fieldIndex < 0 || fieldIndex >= mFieldCount || mHeader[fieldIndex].type != MYSQL_ROW_STRING) {
addError(new ParamError(__FUNCTION__, "invalid field index", fieldIndex));
return nullptr;
}
return (std::string*)mDataBuffer[fieldIndex];
}
inline double* getDecimalRow(int fieldIndex) {
if (fieldIndex < 0 || fieldIndex >= mFieldCount || mHeader[fieldIndex].type != MYSQL_ROW_DECIMAL) {
addError(new ParamError(__FUNCTION__, "invalid field index", fieldIndex));
return nullptr;
}
return (double*)mDataBuffer[fieldIndex];
}
protected:
bool checkIndexValid(int fieldIndex, int rowIndex, MysqlRowType type);
size_t mFieldCount;
size_t mRowCount;
MysqlTableColumn* mHeader;
void** mDataBuffer;
};
#endif //DR_LUA_WEB_MODULE_STRUCTURES_MYSQL_MYSQL_TABLE_ARRAY__H

View File

@ -66,6 +66,7 @@ bool Session::createUser(const std::string& name, const std::string& email, cons
// write user into db
// generate and write email verification into db
// send email
createEmailVerificationCode();
return true;

View File

@ -0,0 +1,16 @@
#include "PrepaireEmailTask.h"
PrepaireEmailTask::PrepaireEmailTask()
{
}
PrepaireEmailTask::~PrepaireEmailTask()
{
}
int PrepaireEmailTask::run()
{
return 0;
}

View File

@ -0,0 +1,23 @@
#ifndef GRADIDO_LOGIN_SERVER_TASKS_PREPAIRE_EMAIL_TASK_INCLUDE
#define GRADIDO_LOGIN_SERVER_TASKS_PREPAIRE_EMAIL_TASK_INCLUDE
#include "Task.h"
class PrepaireEmailTask : public UniLib::controller::Task
{
public:
PrepaireEmailTask();
virtual ~PrepaireEmailTask();
virtual int run();
virtual const char* getResourceType() const { return "PrepaireEmailTask"; };
protected:
private:
};
#endif //GRADIDO_LOGIN_SERVER_TASKS_PREPAIRE_EMAIL_TASK_INCLUDE

View File

@ -8,9 +8,11 @@ class SendEmailTask : public UniLib::controller::Task
{
public:
SendEmailTask();
~SendEmailTask();
virtual ~SendEmailTask();
virtual int run();
virtual const char* getResourceType() const { return "SendEmailTask"; };
protected:
private:

View File

@ -2,18 +2,23 @@
#define GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE
#include "Task.h"
#include "../SingletonManager/ConnectionManager.h"
#include "Poco/Tuple.h"
class WriteIntoDBTask : public UniLib::controller::Task
{
public:
WriteIntoDBTask();
~WriteIntoDBTask();
WriteIntoDBTask(ConnectionType type, std::vector<);
virtual ~WriteIntoDBTask();
virtual int run();
virtual const char* getResourceType() const { return "WriteIntoDBTask"; };
protected:
private:
ConnectionType mConnectionType;
};