mirror of
https://github.com/MariaDB/server.git
synced 2026-05-14 19:07:15 +02:00
Extending the API for json_writer by introdcing
classes for Json_writer_object and Json_writer_array. These classes will be used for the implementation of the optimizer trace.
This commit is contained in:
parent
4d5f85a3ec
commit
6b979416e0
2 changed files with 348 additions and 10 deletions
|
|
@ -16,7 +16,6 @@
|
||||||
#include "mariadb.h"
|
#include "mariadb.h"
|
||||||
#include "sql_priv.h"
|
#include "sql_priv.h"
|
||||||
#include "sql_string.h"
|
#include "sql_string.h"
|
||||||
|
|
||||||
#include "my_json_writer.h"
|
#include "my_json_writer.h"
|
||||||
|
|
||||||
void Json_writer::append_indent()
|
void Json_writer::append_indent()
|
||||||
|
|
@ -62,6 +61,7 @@ void Json_writer::end_object()
|
||||||
indent_level-=INDENT_SIZE;
|
indent_level-=INDENT_SIZE;
|
||||||
if (!first_child)
|
if (!first_child)
|
||||||
append_indent();
|
append_indent();
|
||||||
|
first_child= false;
|
||||||
output.append("}");
|
output.append("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,7 +129,6 @@ void Json_writer::add_ll(longlong val)
|
||||||
add_unquoted_str(buf);
|
add_unquoted_str(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Add a memory size, printing in Kb, Kb, Gb if necessary */
|
/* Add a memory size, printing in Kb, Kb, Gb if necessary */
|
||||||
void Json_writer::add_size(longlong val)
|
void Json_writer::add_size(longlong val)
|
||||||
{
|
{
|
||||||
|
|
@ -173,7 +172,7 @@ void Json_writer::add_null()
|
||||||
|
|
||||||
void Json_writer::add_unquoted_str(const char* str)
|
void Json_writer::add_unquoted_str(const char* str)
|
||||||
{
|
{
|
||||||
if (fmt_helper.on_add_str(str))
|
if (fmt_helper.on_add_str(str, 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!element_started)
|
if (!element_started)
|
||||||
|
|
@ -183,10 +182,9 @@ void Json_writer::add_unquoted_str(const char* str)
|
||||||
element_started= false;
|
element_started= false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Json_writer::add_str(const char *str)
|
void Json_writer::add_str(const char *str)
|
||||||
{
|
{
|
||||||
if (fmt_helper.on_add_str(str))
|
if (fmt_helper.on_add_str(str, 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!element_started)
|
if (!element_started)
|
||||||
|
|
@ -198,12 +196,70 @@ void Json_writer::add_str(const char *str)
|
||||||
element_started= false;
|
element_started= false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function is used to add only num_bytes of str to the output string
|
||||||
|
*/
|
||||||
|
|
||||||
|
void Json_writer::add_str(const char* str, size_t num_bytes)
|
||||||
|
{
|
||||||
|
if (fmt_helper.on_add_str(str, num_bytes))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!element_started)
|
||||||
|
start_element();
|
||||||
|
|
||||||
|
output.append('"');
|
||||||
|
output.append(str, num_bytes);
|
||||||
|
output.append('"');
|
||||||
|
element_started= false;
|
||||||
|
}
|
||||||
|
|
||||||
void Json_writer::add_str(const String &str)
|
void Json_writer::add_str(const String &str)
|
||||||
{
|
{
|
||||||
add_str(str.ptr());
|
add_str(str.ptr(), str.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Json_writer_object::Json_writer_object(Json_writer *writer):Json_writer_struct(writer)
|
||||||
|
{
|
||||||
|
if (my_writer)
|
||||||
|
my_writer->start_object();
|
||||||
|
}
|
||||||
|
|
||||||
|
Json_writer_object::Json_writer_object(Json_writer *writer, const char *str)
|
||||||
|
:Json_writer_struct(writer)
|
||||||
|
{
|
||||||
|
if (my_writer)
|
||||||
|
my_writer->add_member(str).start_object();
|
||||||
|
|
||||||
|
}
|
||||||
|
Json_writer_object::~Json_writer_object()
|
||||||
|
{
|
||||||
|
if (!closed && my_writer)
|
||||||
|
my_writer->end_object();
|
||||||
|
closed= TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Json_writer_array::Json_writer_array(Json_writer *writer):Json_writer_struct(writer)
|
||||||
|
{
|
||||||
|
if (my_writer)
|
||||||
|
my_writer->start_array();
|
||||||
|
}
|
||||||
|
|
||||||
|
Json_writer_array::Json_writer_array(Json_writer *writer, const char *str)
|
||||||
|
:Json_writer_struct(writer)
|
||||||
|
{
|
||||||
|
if (my_writer)
|
||||||
|
my_writer->add_member(str).start_array();
|
||||||
|
|
||||||
|
}
|
||||||
|
Json_writer_array::~Json_writer_array()
|
||||||
|
{
|
||||||
|
if (!closed && my_writer)
|
||||||
|
{
|
||||||
|
my_writer->end_array();
|
||||||
|
closed= TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Single_line_formatting_helper::on_add_member(const char *name)
|
bool Single_line_formatting_helper::on_add_member(const char *name)
|
||||||
{
|
{
|
||||||
|
|
@ -267,11 +323,12 @@ void Single_line_formatting_helper::on_start_object()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Single_line_formatting_helper::on_add_str(const char *str)
|
bool Single_line_formatting_helper::on_add_str(const char *str,
|
||||||
|
size_t num_bytes)
|
||||||
{
|
{
|
||||||
if (state == IN_ARRAY)
|
if (state == IN_ARRAY)
|
||||||
{
|
{
|
||||||
size_t len= strlen(str);
|
size_t len= num_bytes ? num_bytes : strlen(str);
|
||||||
|
|
||||||
// New length will be:
|
// New length will be:
|
||||||
// "$string",
|
// "$string",
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,15 @@
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */
|
||||||
|
|
||||||
|
#ifndef JSON_WRITER_INCLUDED
|
||||||
|
#define JSON_WRITER_INCLUDED
|
||||||
|
#include "my_base.h"
|
||||||
|
#include "sql_select.h"
|
||||||
|
class Opt_trace_stmt;
|
||||||
|
class Opt_trace_context;
|
||||||
class Json_writer;
|
class Json_writer;
|
||||||
|
struct TABLE_LIST;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Single_line_formatting_helper is used by Json_writer to do better formatting
|
Single_line_formatting_helper is used by Json_writer to do better formatting
|
||||||
|
|
@ -85,7 +93,7 @@ public:
|
||||||
void on_start_object();
|
void on_start_object();
|
||||||
// on_end_object() is not needed.
|
// on_end_object() is not needed.
|
||||||
|
|
||||||
bool on_add_str(const char *str);
|
bool on_add_str(const char *str, size_t num_bytes);
|
||||||
|
|
||||||
void flush_on_one_line();
|
void flush_on_one_line();
|
||||||
void disable_and_flush();
|
void disable_and_flush();
|
||||||
|
|
@ -105,7 +113,10 @@ public:
|
||||||
|
|
||||||
/* Add atomic values */
|
/* Add atomic values */
|
||||||
void add_str(const char* val);
|
void add_str(const char* val);
|
||||||
|
void add_str(const char* val, size_t num_bytes);
|
||||||
void add_str(const String &str);
|
void add_str(const String &str);
|
||||||
|
void add_str(Item *item);
|
||||||
|
void add_table_name(JOIN_TAB *tab);
|
||||||
|
|
||||||
void add_ll(longlong val);
|
void add_ll(longlong val);
|
||||||
void add_size(longlong val);
|
void add_size(longlong val);
|
||||||
|
|
@ -151,6 +162,276 @@ public:
|
||||||
String output;
|
String output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* A class to add values to Json_writer_object and Json_writer_array */
|
||||||
|
class Json_value_context
|
||||||
|
{
|
||||||
|
Json_writer* writer;
|
||||||
|
public:
|
||||||
|
void init(Json_writer *my_writer) { writer= my_writer; }
|
||||||
|
void add_str(const char* val)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_str(val);
|
||||||
|
}
|
||||||
|
void add_str(const char* val, size_t length)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_str(val);
|
||||||
|
}
|
||||||
|
void add_str(const String &str)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_str(str);
|
||||||
|
}
|
||||||
|
void add_str(LEX_CSTRING str)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_str(str.str);
|
||||||
|
}
|
||||||
|
void add_str(Item *item)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_str(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_ll(longlong val)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_ll(val);
|
||||||
|
}
|
||||||
|
void add_size(longlong val)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_size(val);
|
||||||
|
}
|
||||||
|
void add_double(double val)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_double(val);
|
||||||
|
}
|
||||||
|
void add_bool(bool val)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_bool(val);
|
||||||
|
}
|
||||||
|
void add_null()
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_null();
|
||||||
|
}
|
||||||
|
void add_table_name(JOIN_TAB *tab)
|
||||||
|
{
|
||||||
|
if (writer)
|
||||||
|
writer->add_table_name(tab);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A common base for Json_writer_object and Json_writer_array */
|
||||||
|
class Json_writer_struct
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
Json_writer* my_writer;
|
||||||
|
Json_value_context context;
|
||||||
|
/*
|
||||||
|
Tells when a json_writer_struct has been closed or not
|
||||||
|
*/
|
||||||
|
bool closed;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Json_writer_struct(Json_writer* writer)
|
||||||
|
{
|
||||||
|
my_writer= writer;
|
||||||
|
context.init(writer);
|
||||||
|
closed= false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
RAII-based class to start/end writing a JSON object into the JSON document
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Json_writer_object:public Json_writer_struct
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void add_member(const char *name)
|
||||||
|
{
|
||||||
|
if (my_writer)
|
||||||
|
my_writer->add_member(name);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Json_writer_object(Json_writer *w);
|
||||||
|
Json_writer_object(Json_writer *w, const char *str);
|
||||||
|
Json_writer_object& add(const char *name, bool value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_bool(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char* name, uint value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char* name, ha_rows value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, longlong value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, double value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_double(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, size_t value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, const char *value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_str(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, const char *value, size_t num_bytes)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_str(value, num_bytes);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, const String &value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_str(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, LEX_CSTRING value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_str(value.str);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add(const char *name, Item *value)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_str(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add_null(const char*name)
|
||||||
|
{
|
||||||
|
add_member(name);
|
||||||
|
context.add_null();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_object& add_table_name(JOIN_TAB *tab)
|
||||||
|
{
|
||||||
|
add_member("table");
|
||||||
|
context.add_table_name(tab);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
void end()
|
||||||
|
{
|
||||||
|
if (my_writer)
|
||||||
|
my_writer->end_object();
|
||||||
|
closed= TRUE;
|
||||||
|
}
|
||||||
|
~Json_writer_object();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
RAII-based class to start/end writing a JSON array into the JSON document
|
||||||
|
*/
|
||||||
|
class Json_writer_array:public Json_writer_struct
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Json_writer_array(Json_writer *w);
|
||||||
|
Json_writer_array(Json_writer *w, const char *str);
|
||||||
|
void end()
|
||||||
|
{
|
||||||
|
if (my_writer)
|
||||||
|
my_writer->end_array();
|
||||||
|
closed= TRUE;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(bool value)
|
||||||
|
{
|
||||||
|
context.add_bool(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(uint value)
|
||||||
|
{
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(ha_rows value)
|
||||||
|
{
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(longlong value)
|
||||||
|
{
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(double value)
|
||||||
|
{
|
||||||
|
context.add_double(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(size_t value)
|
||||||
|
{
|
||||||
|
context.add_ll(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(const char *value)
|
||||||
|
{
|
||||||
|
context.add_str(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(const char *value, size_t num_bytes)
|
||||||
|
{
|
||||||
|
context.add_str(value, num_bytes);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(const String &value)
|
||||||
|
{
|
||||||
|
context.add_str(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(LEX_CSTRING value)
|
||||||
|
{
|
||||||
|
context.add_str(value.str);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add(Item *value)
|
||||||
|
{
|
||||||
|
context.add_str(value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add_null()
|
||||||
|
{
|
||||||
|
context.add_null();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Json_writer_array& add_table_name(JOIN_TAB *tab)
|
||||||
|
{
|
||||||
|
context.add_table_name(tab);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
~Json_writer_array();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
RAII-based helper class to detect incorrect use of Json_writer.
|
RAII-based helper class to detect incorrect use of Json_writer.
|
||||||
|
|
@ -192,4 +473,4 @@ public:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue