File: test_python_execute_func_with_record.cc

package info (click to toggle)
glom 1.30.4-7
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 41,260 kB
  • sloc: ansic: 160,257; cpp: 72,338; javascript: 9,331; sh: 4,971; xml: 476; makefile: 315; perl: 236
file content (140 lines) | stat: -rw-r--r-- 4,304 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <glom/libglom/init.h>
#include <glom/libglom/connectionpool.h>
#include <glom/python_embed/glom_python.h>
#include <libglom/data_structure/glomconversions.h>
#include <libglom/utils.h>
#include <glibmm/convert.h>
#include <glibmm/miscutils.h>
#include <boost/python.hpp>
#include <iostream>

static void on_startup_progress()
{
  std::cout << "Database startup progress" << std::endl;
}

static void on_cleanup_progress()
{
  std::cout << "Database cleanup progress" << std::endl;
}

void cleanup()
{
  auto connection_pool = Glom::ConnectionPool::get_instance();

  const auto stopped = connection_pool->cleanup( sigc::ptr_fun(&on_cleanup_progress) );
  g_assert(stopped);
}

int main()
{
  Glom::libglom_init(); //Also initializes python.

  //Connect to a Glom database
  //A sqlite-based one, to simplify this test.
  // Get a URI for a test file:
  Glib::ustring uri;

  try
  {
    const std::string path =
       Glib::build_filename(GLOM_DOCDIR_EXAMPLES_NOTINSTALLED,
         "sqlite", "test_sqlite_music", "test_sqlite_music.glom");
    uri = Glib::filename_to_uri(path);
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << G_STRFUNC << ": " << ex.what();
    return EXIT_FAILURE;
  }

  g_assert( Glom::Utils::file_exists(uri) );
  //std::cout << "URI=" << uri << std::endl;


  // Load the document:
  Glom::Document document;
  document.set_file_uri(uri);
  int failure_code = 0;
  const auto test = document.load(failure_code);
  //std::cout << "Document load result=" << test << std::endl;

  if(!test)
  {
    std::cerr << G_STRFUNC << ": Document::load() failed with failure_code=" << failure_code << std::endl;
    return EXIT_FAILURE;
  }

  g_assert(!document.get_is_example_file());;

  auto connection_pool = Glom::ConnectionPool::get_instance();
  connection_pool->setup_from_document(&document);

  //This is not really necessary for sqlite-based databases.
  const Glom::ConnectionPool::StartupErrors started =
    connection_pool->startup( sigc::ptr_fun(&on_startup_progress) );
  if(started != Glom::ConnectionPool::Backend::StartupErrors::NONE)
  {
    std::cerr << G_STRFUNC << ": connection_pool->startup(): result=" << Glom::Utils::to_utype(started) << std::endl;
  }
  g_assert(started == Glom::ConnectionPool::Backend::StartupErrors::NONE);

  std::shared_ptr<Glom::SharedConnection> connection = connection_pool->connect();
  g_assert(connection);

  Glib::RefPtr<Gnome::Gda::Connection> gda_connection = connection->get_gda_connection();
  g_assert(connection->get_gda_connection());


  //Some silly python code just to exercise our PyGlomRecord API:
  const char* calculation = "connection = record.connection\nreturn connection.is_opened()";
  Glom::type_map_fields field_values;

  //TODO: Use this: const auto field_values = get_record_field_values_for_calculation(field_in_record.m_table_name, field_in_record.m_key, field_in_record.m_key_value);
  //    if(!field_values.empty())

  //Execute a python function:
  Gnome::Gda::Value value;
  Glib::ustring error_message;
  try
  {
    value = Glom::glom_evaluate_python_function_implementation(
      Glom::Field::glom_field_type::BOOLEAN, calculation, field_values,
      0 /* document */, "" /* table name */,
      std::shared_ptr<Glom::Field>(), Gnome::Gda::Value(), // primary key details. Not used in this test.
      gda_connection,
      error_message);
  }
  catch(const std::exception& ex)
  {
    std::cerr << G_STRFUNC << ": Exception: " << ex.what() << std::endl;
    return EXIT_FAILURE;
  }
  catch(const boost::python::error_already_set& ex)
  {
    std::cerr << G_STRFUNC << ": Exception: boost::python::error_already_set" << std::endl;
    return EXIT_FAILURE;
  }

  //std::cout << "type=" << g_type_name(value.get_value_type()) << std::endl;

  //Check that there was no python error:
  if(!error_message.empty())
  {
    std::cerr << G_STRFUNC << ": Python error: " << error_message << std::endl;
    return EXIT_FAILURE;
  }

  //Check that the return value is of the expected type:
  g_assert(value.get_value_type() == G_TYPE_BOOLEAN);

  //Check that the return value is of the expected value:
  const auto boolval = value.get_boolean();
  g_assert(boolval == true);

  //std::cout << "value=" << value.to_string() << std::endl;

  cleanup();

  return EXIT_SUCCESS;
}