Примеры файлов JSON
Expense.json
[
{
"WHO": "Joe",
"WEEK": [
{
"NUMBER": 3,
"EXPENSE": [
{
"WHAT": "Beer",
"AMOUNT": 18.00
},
{
"WHAT": "Food",
"AMOUNT": 12.00
},
{
"WHAT": "Food",
"AMOUNT": 19.00
},
{
"WHAT": "Car",
"AMOUNT": 20.00
}
]
},
{
"NUMBER": 4,
"EXPENSE": [
{
"WHAT": "Beer",
"AMOUNT": 19.00
},
{
"WHAT": "Beer",
"AMOUNT": 16.00
},
{
"WHAT": "Food",
"AMOUNT": 17.00
},
{
"WHAT": "Food",
"AMOUNT": 17.00
},
{
"WHAT": "Beer",
"AMOUNT": 14.00
}
]
},
{
"NUMBER": 5,
"EXPENSE": [
{
"WHAT": "Beer",
"AMOUNT": 14.00
},
{
"WHAT": "Food",
"AMOUNT": 12.00
}
]
}
]
},
{
"WHO": "Beth",
"WEEK": [
{
"NUMBER": 3,
"EXPENSE": [
{
"WHAT": "Beer",
"AMOUNT": 16.00
}
]
},
{
"NUMBER": 4,
"EXPENSE": [
{
"WHAT": "Food",
"AMOUNT": 17.00
},
{
"WHAT": "Beer",
"AMOUNT": 15.00
}
]
},
{
"NUMBER": 5,
"EXPENSE": [
{
"WHAT": "Food",
"AMOUNT": 12.00
},
{
"WHAT": "Beer",
"AMOUNT": 20.00
}
]
}
]
},
{
"WHO": "Janet",
"WEEK": [
{
"NUMBER": 3,
"EXPENSE": [
{
"WHAT": "Car",
"AMOUNT": 19.00
},
{
"WHAT": "Food",
"AMOUNT": 18.00
},
{
"WHAT": "Beer",
"AMOUNT": 18.00
}
]
},
{
"NUMBER": 4,
"EXPENSE": [
{
"WHAT": "Car",
"AMOUNT": 17.00
}
]
},
{
"NUMBER": 5,
"EXPENSE": [
{
"WHAT": "Beer",
"AMOUNT": 14.00
},
{
"WHAT": "Car",
"AMOUNT": 12.00
},
{
"WHAT": "Beer",
"AMOUNT": 19.00
},
{
"WHAT": "Food",
"AMOUNT": 12.00
}
]
}
]
}
]
Пример OEM
В данном примере показано, как можно реализовать таблицу OEM. Объяснение принципов работы и полное руководство по написанию таблиц OEM для CONNECT выходят за рамки этого документа.
tabfic.h
Файл заголовков tabfic.h:
// TABFIC.H Olivier Bertrand 2008-2010
// External table type to read FIC files
#define TYPE_AM_FIC (AMT)129
typedef class FICDEF *PFICDEF;
typedef class TDBFIC *PTDBFIC;
typedef class FICCOL *PFICCOL;
/* ------------------------- FIC classes ------------------------- */
/*******************************************************************/
/* FIC: OEM table to read FIC files. */
/*******************************************************************/
/*******************************************************************/
/* This function is exported from the Tabfic.dll */
/*******************************************************************/
extern "C" PTABDEF __stdcall GetFIC(PGLOBAL g, void *memp);
/*******************************************************************/
/* FIC table definition class. */
/*******************************************************************/
class FICDEF : public DOSDEF { /* Logical table description */
friend class TDBFIC;
public:
// Constructor
FICDEF(void) {Pseudo = 3;}
// Implementation
virtual const char *GetType(void) {return "FIC";}
// Methods
virtual BOOL DefineAM(PGLOBAL g, LPCSTR am, int poff);
virtual PTDB GetTable(PGLOBAL g, MODE m);
protected:
// No Members
}; // end of class FICDEF
/*******************************************************************/
/* This is the class declaration for the FIC table. */
/*******************************************************************/
class TDBFIC : public TDBFIX {
friend class FICCOL;
public:
// Constructor
TDBFIC(PFICDEF tdp);
// Implementation
virtual AMT GetAmType(void) {return TYPE_AM_FIC;}
// Methods
virtual void ResetDB(void);
virtual int RowNumber(PGLOBAL g, BOOL b = FALSE);
// Database routines
virtual PCOL MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n);
virtual BOOL OpenDB(PGLOBAL g, PSQL sqlp);
virtual int ReadDB(PGLOBAL g);
virtual int WriteDB(PGLOBAL g);
virtual int DeleteDB(PGLOBAL g, int irc);
protected:
// Members
int ReadMode; // To read soft deleted lines
int Rows; // Used for RowID
}; // end of class TDBFIC
/*******************************************************************/
/* Class FICCOL: for Monetary columns. */
/*******************************************************************/
class FICCOL : public DOSCOL {
public:
// Constructors
FICCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp,
PCOL cprec, int i, PSZ am = "FIC");
// Implementation
virtual int GetAmType(void) {return TYPE_AM_FIC;}
// Methods
virtual void ReadColumn(PGLOBAL g);
protected:
// Members
char Fmt; // The column format
}; // end of class FICCOL
tabfic.cpp
Файл исходного кода tabfic.cpp:
/*******************************************************************/
/* FIC: OEM table to read FIC files. */
/*******************************************************************/
#if defined(WIN32)
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff
#include <windows.h>
#endif // WIN32
#include "global.h"
#include "plgdbsem.h"
#include "reldef.h"
#include "filamfix.h"
#include "tabfix.h"
#include "tabfic.h"
int TDB::Tnum;
int DTVAL::Shift;
/*******************************************************************/
/* Initialize the CSORT static members. */
/*******************************************************************/
int CSORT::Limit = 0;
double CSORT::Lg2 = log(2.0);
size_t CSORT::Cpn[1000] = {0}; /* Precalculated cmpnum values */
/* ------------- Implementation of the FIC subtype --------------- */
/*******************************************************************/
/* This function is exported from the DLL. */
/*******************************************************************/
PTABDEF __stdcall GetFIC(PGLOBAL g, void *memp)
{
return new(g, memp) FICDEF;
} // end of GetFIC
/* -------------- Implementation of the FIC classes -------------- */
/*******************************************************************/
/* DefineAM: define specific AM block values from FIC file. */
/*******************************************************************/
BOOL FICDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
{
ReadMode = GetIntCatInfo("Readmode", 0);
// Indicate that we are a BIN format
return DOSDEF::DefineAM(g, "BIN", poff);
} // end of DefineAM
/*******************************************************************/
/* GetTable: makes a new TDB of the proper type. */
/*******************************************************************/
PTDB FICDEF::GetTable(PGLOBAL g, MODE m)
{
return new(g) TDBFIC(this);
} // end of GetTable
/* --------------------------------------------------------------- */
/*******************************************************************/
/* Implementation of the TDBFIC class. */
/*******************************************************************/
TDBFIC::TDBFIC(PFICDEF tdp) : TDBFIX(tdp, NULL)
{
ReadMode = tdp->ReadMode;
Rows = 0;
} // end of TDBFIC constructor
/*******************************************************************/
/* Allocate FIC column description block. */
/*******************************************************************/
PCOL TDBFIC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
{
PCOL colp;
// BINCOL is alright except for the Monetary format
if (cdp->GetFmt() && toupper(*cdp->GetFmt()) == 'M')
colp = new(g) FICCOL(g, cdp, this, cprec, n);
else
colp = new(g) BINCOL(g, cdp, this, cprec, n);
return colp;
} // end of MakeCol
/*******************************************************************/
/* RowNumber: return the ordinal number of the current row. */
/*******************************************************************/
int TDBFIC::RowNumber(PGLOBAL g, BOOL b)
{
return (b) ? Txfp->GetRowID() : Rows;
} // end of RowNumber
/*******************************************************************/
/* FIC Access Method reset table for re-opening. */
/*******************************************************************/
void TDBFIC::ResetDB(void)
{
Rows = 0;
TDBFIX::ResetDB();
} // end of ResetDB
/*******************************************************************/
/* FIC Access Method opening routine. */
/*******************************************************************/
BOOL TDBFIC::OpenDB(PGLOBAL g, PSQL sqlp)
{
if (Use == USE_OPEN) {
// Table already open, just replace it at its beginning.
return TDBFIX::OpenDB(g);
} // endif use
if (Mode != MODE_READ) {
// Currently FIC tables cannot be modified.
strcpy(g->Message, "FIC tables are read only");
return TRUE;
} // endif Mode
/*****************************************************************/
/* Physically open the FIC file. */
/*****************************************************************/
if (TDBFIX::OpenDB(g))
return TRUE;
Use = USE_OPEN;
return FALSE;
} // end of OpenDB
/*******************************************************************/
/* ReadDB: Data Base read routine for FIC access method. */
/*******************************************************************/
int TDBFIC::ReadDB(PGLOBAL g)
{
int rc;
/*****************************************************************/
/* Now start the reading process. */
/*****************************************************************/
do {
rc = TDBFIX::ReadDB(g);
} while (rc == RC_OK && ((ReadMode == 0 && *To_Line == '*') ||
(ReadMode == 2 && *To_Line != '*')));
Rows++;
return rc;
} // end of ReadDB
/*******************************************************************/
/* WriteDB: Data Base write routine for FIC access methods. */
/*******************************************************************/
int TDBFIC::WriteDB(PGLOBAL g)
{
strcpy(g->Message, "FIC tables are read only");
return RC_FX;
} // end of WriteDB
/*******************************************************************/
/* Data Base delete line routine for FIC access methods. */
/*******************************************************************/
int TDBFIC::DeleteDB(PGLOBAL g, int irc)
{
strcpy(g->Message, "Delete not enabled for FIC tables");
return RC_FX;
} // end of DeleteDB
// ---------------------- FICCOL functions --------------------------
/*******************************************************************/
/* FICCOL public constructor. */
/*******************************************************************/
FICCOL::FICCOL(PGLOBAL g, PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i,
PSZ am) : DOSCOL(g, cdp, tdbp, cprec, i, am)
{
// Set additional FIC access method information for column.
Fmt = toupper(*cdp->GetFmt()); // Column format
} // end of FICCOL constructor
/*******************************************************************/
/* Handle the monetary value of this column. It is a big integer */
/* that represents the value multiplied by 1000. */
/* In this function we translate it to a double float value. */
/*******************************************************************/
void FICCOL::ReadColumn(PGLOBAL g)
{
char *p;
int rc;
uint n;
double fmon;
PTDBFIC tdbp = (PTDBFIC)To_Tdb;
/*****************************************************************/
/* If physical reading of the line was deferred, do it now. */
/*****************************************************************/
if (!tdbp->IsRead())
if ((rc = tdbp->ReadBuffer(g)) != RC_OK) {
if (rc == RC_EF)
sprintf(g->Message, MSG(INV_DEF_READ), rc);
longjmp(g->jumper[g->jump_level], 11);
} // endif
p = tdbp->To_Line + Deplac;
/*****************************************************************/
/* Set Value from the line field. */
/*****************************************************************/
if (*(SHORT*)(p + 8) < 0) {
n = ~*(SHORT*)(p + 8);
fmon = (double)n;
fmon *= 4294967296.0;
n = ~*(int*)(p + 4);
fmon += (double)n;
fmon *= 4294967296.0;
n = ~*(int*)p;
fmon += (double)n;
fmon++;
fmon /= 1000000.0;
fmon = -fmon;
} else {
fmon = ((double)*(USHORT*)(p + 8));
fmon *= 4294967296.0;
fmon += ((double)*(ULONG*)(p + 4));
fmon *= 4294967296.0;
fmon += ((double)*(ULONG*)p);
fmon /= 1000000.0;
} // enif neg
Value->SetValue(fmon);
} // end of ReadColumn
tabfic.def
Файл tabfic.def: (требуется только в Windows)
LIBRARY TABFIC DESCRIPTION 'FIC files' EXPORTS GetFIC @1
JSON UDF в отдельной библиотеке
Несмотря на то, что JSON UDF можно удобно включить в модуль библиотеки CONNECT, в некоторых случаях может потребоваться разместить их в отдельной библиотеке.
Это необходимо, если CONNECT компилируется встраиваемо или если вы хотите протестировать или использовать эти UDF с другими версиями MariaDB, не содержащими их.
Для этого необходимо получить доступ к последнему исходному коду MariaDB. Затем создайте проект, содержащий следующие файлы:
- jsonudf.cpp
- json.cpp
- value.cpp
- osutil.c
- plugutil.c
- maputil.cpp
- jsonutil.cpp
jsonutil.cpp не входит в дистрибутив исходного кода, его необходимо создать самостоятельно по приведенному ниже образцу:
#include "my_global.h"
#include "mysqld.h"
#include "plugin.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include "global.h"
extern "C" int GetTraceValue(void) { return 0; }
uint GetJsonGrpSize(void) { return 100; }
/***********************************************************************/
/* These replace missing function of the (not used) DTVAL class. */
/***********************************************************************/
typedef struct _datpar *PDTP;
PDTP MakeDateFormat(PGLOBAL, PSZ, bool, bool, int) { return NULL; }
int ExtractDate(char*, PDTP, int, int val[6]) { return 0; }
#ifdef __WIN__
my_bool CloseFileHandle(HANDLE h)
{
return !CloseHandle(h);
} /* end of CloseFileHandle */
#else /* UNIX */
my_bool CloseFileHandle(HANDLE h)
{
return (close(h)) ? TRUE : FALSE;
} /* end of CloseFileHandle */
int GetLastError()
{
return errno;
} /* end of GetLastError */
#endif // UNIX
/***********************************************************************/
/* Program for sub-allocating one item in a storage area. */
/* Note: This function is equivalent to PlugSubAlloc except that in */
/* case of insufficient memory, it returns NULL instead of doing a */
/* long jump. The caller must test the return value for error. */
/***********************************************************************/
void *PlgDBSubAlloc(PGLOBAL g, void *memp, size_t size)
{
PPOOLHEADER pph; // Points on area header.
if (!memp) // Allocation is to be done in the Sarea
memp = g->Sarea;
size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */
pph = (PPOOLHEADER)memp;
if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */
sprintf(g->Message,
"Not enough memory in Work area for request of %d (used=%d free=%d)",
(int)size, pph->To_Free, pph->FreeBlk);
return NULL;
} // endif size
// Do the suballocation the simplest way
memp = MakePtr(memp, pph->To_Free); // Points to sub_allocated block
pph->To_Free += size; // New offset of pool free block
pph->FreeBlk -= size; // New size of pool free block
return (memp);
} // end of PlgDBSubAlloc
Вы можете создать файл, скопировав и вставив код из приведенного выше образца.
Установите все дополнительные директории включения в директории включения MariaDB, используемые при компиляции плагина, плюс ссылки на директории хранения/подключения, и скомпилируйте, как и любой другой UDF, присвоив любое имя созданному модулю библиотеки (я использовал jsonudf.dll в Windows).
Затем вы можете создать функции, используя это имя в качестве параметра soname.
При использовании UDF таким образом существуют некоторые ограничения:
- Переменная connect_json_grp_size недоступна. Размер группы задан равным 100.
- В случае ошибки предупреждения заменяются сообщениями, отправленными в stderr.
- Отсутствует отслеживание.
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/json-sample-files/