/* Build like so:
 * gcc test_libgda_binary.c `pkg-config libgda-5.0 --cflags --libs`
 */

#include <libgda/libgda.h>

GdaConnection* conn = NULL;


int main()
{
	gda_init();

	GError* error = NULL;
	conn = gda_connection_open_from_string("PostgreSQL",
		"HOST=localhost;PORT=5433;DB_NAME=glom_example_smallbusiness_v2",
		"USERNAME=glom_default_developer_user;PASSWORD=glom_default_developer_password",
		GDA_CONNECTION_OPTIONS_SQL_IDENTIFIERS_CASE_SENSITIVE,
		&error);
	
	if (error) {
		g_warning("gda_connection_open_from_string() failed: %s\n", error->message);
		g_clear_error(&error);
		return 0;
	}


  const int data_original_size = 7;
  guchar data_original[7];
  data_original[0] = 255;
  data_original[1] = 216;  
  data_original[2] = 255;
  data_original[3] = 224;
  data_original[4] = 0;
  data_original[5] = 16;
  data_original[6] = 74;
  
  //UPDATE:
  GValue* value_original = gda_value_new_binary(data_original, data_original_size);
    
  GdaSqlBuilder* builder = gda_sql_builder_new(GDA_SQL_STATEMENT_UPDATE);
  gda_sql_builder_set_table(builder, "contacts");
  gda_sql_builder_add_field_value_as_gvalue(builder, "picture", value_original);
 
  guint id_cond = gda_sql_builder_add_cond (builder, GDA_SQL_OPERATOR_TYPE_EQ,
   gda_sql_builder_add_id (builder, "contact_id"),
   gda_sql_builder_add_expr (builder, NULL, G_TYPE_INT, 1),
     0);
  gda_sql_builder_set_where(builder, id_cond);

  GdaStatement* stmt = gda_sql_builder_get_statement(builder, &error);
  if (error) {
		g_warning("gda_sql_builder_get_statement() failed: %s\n", error->message);
		g_clear_error(&error);
	}
	g_assert(stmt);

  const gint result = gda_connection_statement_execute_non_select(
    conn, stmt, NULL, NULL, &error);
  if (error) {
		g_warning("gda_connection_statement_execute_select() failed: %s\n", error->message);
		g_clear_error(&error);
		return 0;
	}
	g_assert(result != -1);
	g_object_unref (builder);
 
  
  //SELECT:
  builder = gda_sql_builder_new(GDA_SQL_STATEMENT_SELECT);
  gda_sql_builder_select_add_target(builder, "contacts", NULL);
  gda_sql_builder_select_add_field(builder, "picture", "contacts", NULL);

  id_cond = gda_sql_builder_add_cond (builder, GDA_SQL_OPERATOR_TYPE_EQ,
   gda_sql_builder_add_id (builder, "contact_id"),
   gda_sql_builder_add_expr (builder, NULL, G_TYPE_INT, 1),
     0);
  gda_sql_builder_set_where(builder, id_cond);

  stmt = gda_sql_builder_get_statement(builder, &error);
  if (error) {
		g_warning("gda_sql_builder_get_statement() failed: %s\n", error->message);
		g_clear_error(&error);
	}
	g_assert(stmt);

  GdaDataModel* model = gda_connection_statement_execute_select(
    conn, stmt, NULL, &error);
  if (error) {
		g_warning("gda_connection_statement_execute_select() failed: %s\n", error->message);
		g_clear_error(&error);
		return 0;
	}
	g_assert(model);
	g_assert(gda_data_model_get_n_rows(model) > 0);
 	g_assert(gda_data_model_get_n_columns(model) > 0);
 	
 	const GValue* value_read = gda_data_model_get_value_at(model, 0, 0, &error);
 	if (error) {
		g_warning("gda_data_model_get_value_at() failed: %s\n", error->message);
		g_clear_error(&error);
		return 0;
	}
	
	//Test the value that was read out of the database:
	const GdaBinary* binary_read = gda_value_get_binary(value_read);
	g_assert(binary_read);
	g_assert(binary_read->data);
	g_assert(binary_read->binary_length >= data_original_size);
	
	int i = 0;
	for(i = 0; i < data_original_size; i++)
	{
	  const guchar ch_read = (binary_read->data)[i];
	  const guchar ch_original = data_original[i];
	  if(ch_read != ch_original)
	  {
	    g_printf("original %d: ch_read=%d, ch_original=%d\n", i, (gint)ch_read, (gint)ch_original);
	  }
	}


	return 0;
}
