36 if( _apply_undo ) _db.undo();
43 if( _disable_on_exit ) _db.
disable();
48 if( _disabled && !force_enable )
return session(*
this);
49 bool disable_on_exit = _disabled && force_enable;
56 _stack.emplace_back();
58 return session(*
this, disable_on_exit );
62 if( _disabled )
return;
65 _stack.emplace_back();
66 auto& state = _stack.back();
68 auto itr = state.old_index_next_ids.find( index_id );
69 if( itr == state.old_index_next_ids.end() )
70 state.old_index_next_ids[index_id] = obj.
id;
71 state.new_ids.insert(obj.
id);
75 if( _disabled )
return;
78 _stack.emplace_back();
79 auto& state = _stack.back();
80 if( state.new_ids.find(obj.
id) != state.new_ids.end() )
82 auto itr = state.old_values.find(obj.
id);
83 if( itr != state.old_values.end() )
return;
84 state.old_values[obj.
id] = obj.
clone();
88 if( _disabled )
return;
91 _stack.emplace_back();
104 if( state.
removed.count(obj.
id) > 0 )
return;
108 void undo_database::undo()
114 auto& state = _stack.back();
115 for(
auto& item : state.old_values )
117 _db.
modify( _db.
get_object( item.second->id ), [&](
object& obj ){ obj.move_from( *item.second ); } );
120 for(
auto ritr = state.new_ids.begin(); ritr != state.new_ids.end(); ++ritr )
125 for(
auto& item : state.old_index_next_ids )
130 for(
auto& item : state.removed )
131 _db.
insert( std::move(*item.second) );
138 void undo_database::merge()
141 if( _active_sessions == 1 && _stack.size() == 1 )
148 auto& state = _stack.back();
149 auto& prev_state = _stack[_stack.size()-2];
194 for(
auto& obj : state.old_values )
196 if( prev_state.new_ids.find(obj.second->id) != prev_state.new_ids.end() )
201 if( prev_state.old_values.find(obj.second->id) != prev_state.old_values.end() )
207 assert( prev_state.removed.find(obj.second->id) == prev_state.removed.end() );
209 prev_state.old_values[obj.second->id] = std::move(obj.second);
213 for(
auto id : state.new_ids )
214 prev_state.new_ids.insert(
id);
217 for(
auto& item : state.old_index_next_ids )
219 if( prev_state.old_index_next_ids.find( item.first ) == prev_state.old_index_next_ids.end() )
222 prev_state.old_index_next_ids[item.first] = item.second;
234 for(
auto& obj : state.removed )
236 if( prev_state.new_ids.find(obj.second->id) != prev_state.new_ids.end() )
239 prev_state.new_ids.erase(obj.second->id);
242 auto it = prev_state.old_values.find(obj.second->id);
243 if( it != prev_state.old_values.end() )
246 prev_state.removed[obj.second->id] = std::move(it->second);
247 prev_state.old_values.erase(obj.second->id);
251 assert( prev_state.removed.find( obj.second->id ) == prev_state.removed.end() );
253 prev_state.removed[obj.second->id] = std::move(obj.second);
258 void undo_database::commit()
271 auto& state = _stack.back();
273 for(
auto& item : state.old_values )
275 _db.
modify( _db.
get_object( item.second->id ), [&](
object& obj ){ obj.move_from( *item.second ); } );
278 for(
auto ritr = state.new_ids.begin(); ritr != state.new_ids.end(); ++ritr )
283 for(
auto& item : state.old_index_next_ids )
288 for(
auto& item : state.removed )
289 _db.
insert( std::move(*item.second) );
304 return _stack.back();