Skip to content

Commit 210fde0

Browse files
authored
Merge pull request #2324 from joto/refactor-lua-wrapper
Refactor: Split out some code from output_flex_t class
2 parents e0c6cdf + 87b9417 commit 210fde0

7 files changed

+295
-223
lines changed

src/flex-lua-expire-output.cpp

+81-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
#include "expire-output.hpp"
1313
#include "format.hpp"
1414
#include "lua-utils.hpp"
15-
#include "pgsql.hpp"
16-
#include "util.hpp"
1715

1816
#include <lua.hpp>
1917

@@ -67,6 +65,13 @@ create_expire_output(lua_State *lua_state, std::string const &default_schema,
6765
return new_expire_output;
6866
}
6967

68+
TRAMPOLINE_WRAPPED_OBJECT(expire_output, __tostring)
69+
TRAMPOLINE_WRAPPED_OBJECT(expire_output, filename)
70+
TRAMPOLINE_WRAPPED_OBJECT(expire_output, maxzoom)
71+
TRAMPOLINE_WRAPPED_OBJECT(expire_output, minzoom)
72+
TRAMPOLINE_WRAPPED_OBJECT(expire_output, schema)
73+
TRAMPOLINE_WRAPPED_OBJECT(expire_output, table)
74+
7075
} // anonymous namespace
7176

7277
int setup_flex_expire_output(lua_State *lua_state,
@@ -88,3 +93,77 @@ int setup_flex_expire_output(lua_State *lua_state,
8893

8994
return 1;
9095
}
96+
97+
/**
98+
* Define the osm2pgsql.ExpireOutput class/metatable.
99+
*/
100+
void lua_wrapper_expire_output::init(lua_State *lua_state)
101+
{
102+
lua_getglobal(lua_state, "osm2pgsql");
103+
if (luaL_newmetatable(lua_state, osm2pgsql_expire_output_name) != 1) {
104+
throw std::runtime_error{"Internal error: Lua newmetatable failed."};
105+
}
106+
lua_pushvalue(lua_state, -1); // Copy of new metatable
107+
108+
// Add metatable as osm2pgsql.ExpireOutput so we can access it from Lua
109+
lua_setfield(lua_state, -3, "ExpireOutput");
110+
111+
// Now add functions to metatable
112+
lua_pushvalue(lua_state, -1);
113+
lua_setfield(lua_state, -2, "__index");
114+
luaX_add_table_func(lua_state, "__tostring",
115+
lua_trampoline_expire_output___tostring);
116+
luaX_add_table_func(lua_state, "filename",
117+
lua_trampoline_expire_output_filename);
118+
luaX_add_table_func(lua_state, "maxzoom",
119+
lua_trampoline_expire_output_maxzoom);
120+
luaX_add_table_func(lua_state, "minzoom",
121+
lua_trampoline_expire_output_minzoom);
122+
luaX_add_table_func(lua_state, "schema",
123+
lua_trampoline_expire_output_schema);
124+
luaX_add_table_func(lua_state, "table", lua_trampoline_expire_output_table);
125+
126+
lua_pop(lua_state, 2);
127+
}
128+
129+
int lua_wrapper_expire_output::__tostring() const
130+
{
131+
std::string const str =
132+
fmt::format("osm2pgsql.ExpireOutput[minzoom={},maxzoom={},filename={},"
133+
"schema={},table={}]",
134+
self().minzoom(), self().maxzoom(), self().filename(),
135+
self().schema(), self().table());
136+
luaX_pushstring(lua_state(), str);
137+
138+
return 1;
139+
}
140+
141+
int lua_wrapper_expire_output::filename() const
142+
{
143+
luaX_pushstring(lua_state(), self().filename());
144+
return 1;
145+
}
146+
147+
int lua_wrapper_expire_output::maxzoom() const
148+
{
149+
lua_pushinteger(lua_state(), self().maxzoom());
150+
return 1;
151+
}
152+
153+
int lua_wrapper_expire_output::minzoom() const
154+
{
155+
lua_pushinteger(lua_state(), self().minzoom());
156+
return 1;
157+
}
158+
159+
int lua_wrapper_expire_output::schema() const
160+
{
161+
luaX_pushstring(lua_state(), self().schema());
162+
return 1;
163+
}
164+
165+
int lua_wrapper_expire_output::table() const
166+
{
167+
luaX_pushstring(lua_state(), self().table());
168+
return 1;
169+
}

src/flex-lua-expire-output.hpp

+23-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
* For a full list of authors see the git log.
1111
*/
1212

13-
#include "expire-output.hpp"
13+
#include "flex-lua-wrapper.hpp"
1414

15+
#include <string>
1516
#include <vector>
1617

18+
class expire_output_t;
1719
struct lua_State;
1820

1921
static char const *const osm2pgsql_expire_output_name =
@@ -23,4 +25,24 @@ int setup_flex_expire_output(lua_State *lua_state,
2325
std::string const &default_schema,
2426
std::vector<expire_output_t> *expire_outputs);
2527

28+
class lua_wrapper_expire_output : public lua_wrapper_base<expire_output_t>
29+
{
30+
public:
31+
static void init(lua_State *lua_state);
32+
33+
lua_wrapper_expire_output(lua_State *lua_state,
34+
expire_output_t *expire_output)
35+
: lua_wrapper_base(lua_state, expire_output)
36+
{
37+
}
38+
39+
int __tostring() const;
40+
int filename() const;
41+
int maxzoom() const;
42+
int minzoom() const;
43+
int schema() const;
44+
int table() const;
45+
46+
}; // class lua_wrapper_expire_output
47+
2648
#endif // OSM2PGSQL_FLEX_LUA_EXPIRE_OUTPUT_HPP

src/flex-lua-table.cpp

+86
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
#include "flex-lua-index.hpp"
1515
#include "flex-table.hpp"
1616
#include "lua-utils.hpp"
17+
#include "output-flex.hpp"
1718
#include "pgsql-capabilities.hpp"
19+
#include "util.hpp"
1820

1921
#include <lua.hpp>
2022

@@ -416,6 +418,12 @@ void setup_flex_table_indexes(lua_State *lua_state, flex_table_t *table,
416418
lua_pop(lua_state, 1); // "indexes"
417419
}
418420

421+
TRAMPOLINE_WRAPPED_OBJECT(table, __tostring)
422+
TRAMPOLINE_WRAPPED_OBJECT(table, cluster)
423+
TRAMPOLINE_WRAPPED_OBJECT(table, columns)
424+
TRAMPOLINE_WRAPPED_OBJECT(table, name)
425+
TRAMPOLINE_WRAPPED_OBJECT(table, schema)
426+
419427
} // anonymous namespace
420428

421429
int setup_flex_table(lua_State *lua_state, std::vector<flex_table_t> *tables,
@@ -442,3 +450,81 @@ int setup_flex_table(lua_State *lua_state, std::vector<flex_table_t> *tables,
442450

443451
return 1;
444452
}
453+
454+
/**
455+
* Define the osm2pgsql.Table class/metatable.
456+
*/
457+
void lua_wrapper_table::init(lua_State *lua_state)
458+
{
459+
lua_getglobal(lua_state, "osm2pgsql");
460+
if (luaL_newmetatable(lua_state, osm2pgsql_table_name) != 1) {
461+
throw std::runtime_error{"Internal error: Lua newmetatable failed."};
462+
}
463+
lua_pushvalue(lua_state, -1); // Copy of new metatable
464+
465+
// Add metatable as osm2pgsql.Table so we can access it from Lua
466+
lua_setfield(lua_state, -3, "Table");
467+
468+
// Now add functions to metatable
469+
lua_pushvalue(lua_state, -1);
470+
lua_setfield(lua_state, -2, "__index");
471+
luaX_add_table_func(lua_state, "__tostring",
472+
lua_trampoline_table___tostring);
473+
luaX_add_table_func(lua_state, "insert", lua_trampoline_table_insert);
474+
luaX_add_table_func(lua_state, "name", lua_trampoline_table_name);
475+
luaX_add_table_func(lua_state, "schema", lua_trampoline_table_schema);
476+
luaX_add_table_func(lua_state, "cluster", lua_trampoline_table_cluster);
477+
luaX_add_table_func(lua_state, "columns", lua_trampoline_table_columns);
478+
479+
lua_pop(lua_state, 2);
480+
}
481+
482+
int lua_wrapper_table::__tostring() const
483+
{
484+
std::string const str{fmt::format("osm2pgsql.Table[{}]", self().name())};
485+
luaX_pushstring(lua_state(), str);
486+
487+
return 1;
488+
}
489+
490+
int lua_wrapper_table::cluster() const
491+
{
492+
lua_pushboolean(lua_state(), self().cluster_by_geom());
493+
return 1;
494+
}
495+
496+
int lua_wrapper_table::columns() const
497+
{
498+
lua_createtable(lua_state(), (int)self().num_columns(), 0);
499+
500+
int n = 0;
501+
for (auto const &column : self().columns()) {
502+
lua_pushinteger(lua_state(), ++n);
503+
lua_newtable(lua_state());
504+
505+
luaX_add_table_str(lua_state(), "name", column.name().c_str());
506+
luaX_add_table_str(lua_state(), "type", column.type_name().c_str());
507+
luaX_add_table_str(lua_state(), "sql_type",
508+
column.sql_type_name().c_str());
509+
luaX_add_table_str(lua_state(), "sql_modifiers",
510+
column.sql_modifiers().c_str());
511+
luaX_add_table_bool(lua_state(), "not_null", column.not_null());
512+
luaX_add_table_bool(lua_state(), "create_only", column.create_only());
513+
514+
lua_rawset(lua_state(), -3);
515+
}
516+
517+
return 1;
518+
}
519+
520+
int lua_wrapper_table::name() const
521+
{
522+
luaX_pushstring(lua_state(), self().name());
523+
return 1;
524+
}
525+
526+
int lua_wrapper_table::schema() const
527+
{
528+
luaX_pushstring(lua_state(), self().schema());
529+
return 1;
530+
}

src/flex-lua-table.hpp

+20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
* For a full list of authors see the git log.
1111
*/
1212

13+
#include "flex-lua-wrapper.hpp"
14+
1315
#include <string>
1416
#include <vector>
1517

@@ -24,4 +26,22 @@ int setup_flex_table(lua_State *lua_state, std::vector<flex_table_t> *tables,
2426
std::string const &default_schema, bool updatable,
2527
bool append_mode);
2628

29+
class lua_wrapper_table : public lua_wrapper_base<flex_table_t>
30+
{
31+
public:
32+
static void init(lua_State *lua_state);
33+
34+
lua_wrapper_table(lua_State *lua_state, flex_table_t *table)
35+
: lua_wrapper_base(lua_state, table)
36+
{
37+
}
38+
39+
int __tostring() const;
40+
int cluster() const;
41+
int columns() const;
42+
int name() const;
43+
int schema() const;
44+
45+
}; // class lua_wrapper_table
46+
2747
#endif // OSM2PGSQL_FLEX_LUA_TABLE_HPP

src/flex-lua-wrapper.hpp

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#ifndef OSM2PGSQL_FLEX_LUA_WRAPPER_HPP
2+
#define OSM2PGSQL_FLEX_LUA_WRAPPER_HPP
3+
4+
/**
5+
* SPDX-License-Identifier: GPL-2.0-or-later
6+
*
7+
* This file is part of osm2pgsql (https://osm2pgsql.org/).
8+
*
9+
* Copyright (C) 2006-2025 by the osm2pgsql developer community.
10+
* For a full list of authors see the git log.
11+
*/
12+
13+
#include "output-flex.hpp"
14+
15+
#include <exception>
16+
17+
#define TRAMPOLINE_WRAPPED_OBJECT(obj_name, func_name) \
18+
int lua_trampoline_##obj_name##_##func_name(lua_State *lua_state) \
19+
{ \
20+
try { \
21+
auto *flex = \
22+
static_cast<output_flex_t *>(luaX_get_context(lua_state)); \
23+
auto &obj = flex->get_##obj_name##_from_param(); \
24+
return lua_wrapper_##obj_name{lua_state, &obj}.func_name(); \
25+
} catch (std::exception const &e) { \
26+
return luaL_error(lua_state, "Error in '" #func_name "': %s\n", \
27+
e.what()); \
28+
} catch (...) { \
29+
return luaL_error(lua_state, \
30+
"Unknown error in '" #func_name "'.\n"); \
31+
} \
32+
}
33+
34+
struct lua_State;
35+
36+
/**
37+
* Helper class for wrapping C++ classes in Lua "classes".
38+
*/
39+
template <typename WRAPPED>
40+
class lua_wrapper_base
41+
{
42+
public:
43+
lua_wrapper_base(lua_State *lua_state, WRAPPED *wrapped)
44+
: m_lua_state(lua_state), m_self(wrapped)
45+
{
46+
}
47+
48+
protected:
49+
lua_State *lua_state() const noexcept { return m_lua_state; }
50+
51+
WRAPPED const &self() const noexcept { return *m_self; }
52+
WRAPPED &self() noexcept { return *m_self; }
53+
54+
private:
55+
lua_State *m_lua_state;
56+
WRAPPED *m_self;
57+
58+
}; // class lua_wrapper_base;
59+
60+
#endif // OSM2PGSQL_FLEX_LUA_WRAPPER_HPP

0 commit comments

Comments
 (0)