Skip to content

Commit 227199f

Browse files
committed
Add return values from insert
1 parent 080e996 commit 227199f

File tree

3 files changed

+73
-15
lines changed

3 files changed

+73
-15
lines changed

flex-config/new-insert-syntax.lua

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,23 @@
66
--
77
-- Note that the insert() function is used instead of the old add_row()!
88

9+
-- The following magic can be used to wrap the internal "insert" function
10+
local orig_insert = osm2pgsql.Table.insert
11+
local function my_insert(table, data)
12+
local json = require 'json'
13+
inserted, message, column, object = orig_insert(table, data)
14+
if not inserted then
15+
for key, value in pairs(data) do
16+
if type(value) == 'userdata' then
17+
data[key] = tostring(value)
18+
end
19+
end
20+
print("insert() failed: " .. message .. " column='" .. column .. "' object='" .. json.encode(object) .. "' data='" .. json.encode(data) .. "'")
21+
end
22+
end
23+
osm2pgsql.Table.insert = my_insert
24+
25+
926
local tables = {}
1027

1128
-- This table will get all nodes and areas with an "addr:street" tag, for
@@ -35,7 +52,7 @@ tables.major_roads = osm2pgsql.define_way_table('major_roads', {
3552

3653
tables.polygons = osm2pgsql.define_area_table('polygons', {
3754
{ column = 'tags', type = 'jsonb' },
38-
{ column = 'geom', type = 'geometry' },
55+
{ column = 'geom', type = 'geometry', not_null = true },
3956
{ column = 'area4326', type = 'real' },
4057
{ column = 'area3857', type = 'real' }
4158
})

src/db-copy-mgr.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ class db_copy_mgr_t
4343

4444
m_current = std::make_unique<db_cmd_copy_delete_t<DELETER>>(table);
4545
}
46+
m_committed = m_current->buffer.size();
47+
}
48+
49+
void rollback_line()
50+
{
51+
assert(m_current);
52+
m_current->buffer.resize(m_committed);
4653
}
4754

4855
/**
@@ -356,6 +363,7 @@ class db_copy_mgr_t
356363

357364
std::shared_ptr<db_copy_thread_t> m_processor;
358365
std::unique_ptr<db_cmd_copy_delete_t<DELETER>> m_current;
366+
std::size_t m_committed = 0;
359367
};
360368

361369
#endif // OSM2PGSQL_DB_COPY_MGR_HPP

src/output-flex.cpp

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,28 @@ static int sgn(double val) noexcept
254254
return 0;
255255
}
256256

257+
class not_null_exception : public std::runtime_error
258+
{
259+
public:
260+
not_null_exception(std::string const &message,
261+
flex_table_column_t const *column)
262+
: std::runtime_error(message), m_column(column)
263+
{}
264+
265+
flex_table_column_t const &column() const noexcept { return *m_column; }
266+
267+
private:
268+
flex_table_column_t const *m_column;
269+
}; // class not_null_exception
270+
257271
static void write_null(db_copy_mgr_t<db_deleter_by_type_and_id_t> *copy_mgr,
258272
flex_table_column_t const &column)
259273
{
260274
if (column.not_null()) {
261-
throw std::runtime_error{
275+
throw not_null_exception{
262276
"Can not add NULL to column '{}' declared NOT NULL."_format(
263-
column.name())};
277+
column.name()),
278+
&column};
264279
}
265280
copy_mgr->add_null_column();
266281
}
@@ -1572,22 +1587,33 @@ int output_flex_t::table_insert()
15721587
table_connection.new_line();
15731588
auto *copy_mgr = table_connection.copy_mgr();
15741589

1575-
for (auto const &column : table_connection.table()) {
1576-
if (column.create_only()) {
1577-
continue;
1578-
}
1579-
if (column.type() == table_column_type::id_type) {
1580-
copy_mgr->add_column(type_to_char(object.type()));
1581-
} else if (column.type() == table_column_type::id_num) {
1582-
copy_mgr->add_column(id);
1583-
} else {
1584-
write_column(copy_mgr, column);
1590+
try {
1591+
for (auto const &column : table_connection.table()) {
1592+
if (column.create_only()) {
1593+
continue;
1594+
}
1595+
if (column.type() == table_column_type::id_type) {
1596+
copy_mgr->add_column(type_to_char(object.type()));
1597+
} else if (column.type() == table_column_type::id_num) {
1598+
copy_mgr->add_column(id);
1599+
} else {
1600+
write_column(copy_mgr, column);
1601+
}
15851602
}
1603+
} catch (not_null_exception const &e) {
1604+
copy_mgr->rollback_line();
1605+
lua_pushboolean(lua_state(), false);
1606+
lua_pushstring(lua_state(), "null value in not null column.");
1607+
lua_pushstring(lua_state(), e.column().name().c_str());
1608+
push_osm_object_to_lua_stack(lua_state(), object,
1609+
get_options()->extra_attributes);
1610+
return 4;
15861611
}
15871612

15881613
copy_mgr->finish_line();
15891614

1590-
return 0;
1615+
lua_pushboolean(lua_state(), true);
1616+
return 1;
15911617
}
15921618

15931619
int output_flex_t::table_columns()
@@ -2184,10 +2210,17 @@ void output_flex_t::init_lua(std::string const &filename)
21842210

21852211
lua_setglobal(lua_state(), "osm2pgsql");
21862212

2187-
// Define "osmpgsql.table" metatable
2213+
// Define "osm2pgsql.table" metatable
2214+
lua_getglobal(lua_state(), "osm2pgsql");
21882215
if (luaL_newmetatable(lua_state(), osm2pgsql_table_name) != 1) {
21892216
throw std::runtime_error{"Internal error: Lua newmetatable failed."};
21902217
}
2218+
lua_pushvalue(lua_state(), -1); // Copy of new metatable
2219+
2220+
// Add metatable as osm2pgsql.Table so we can access it from Lua
2221+
lua_setfield(lua_state(), -3, "Table");
2222+
2223+
// Now add functions to metatable
21912224
lua_pushvalue(lua_state(), -1);
21922225
lua_setfield(lua_state(), -2, "__index");
21932226
luaX_add_table_func(lua_state(), "__tostring",

0 commit comments

Comments
 (0)