Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions flatdata-cpp/include/flatdata/ArchiveBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ArchiveBuilder
const flatdata::ResourceStorage& storage( ) const;
bool is_created( ) const;
void check_created( ) const;
void clean_up_signature( flatdata::ResourceStorage& storage );

private:
std::shared_ptr< flatdata::ResourceStorage > m_storage;
Expand Down
77 changes: 77 additions & 0 deletions flatdata-cpp/include/flatdata/FileResourceStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ class FileResourceStorage : public ResourceStorage

bool exists( const char* key ) override;

void remove_resource( const char* resource_name, const char* expected_schema ) override;

void remove_multivector_index_resource( const char* resource_name,
const char* expected_schema ) override;

protected:
std::shared_ptr< std::ostream > create_output_stream( const char* key ) override;
MemoryDescriptor read_resource( const char* key ) override;
Expand Down Expand Up @@ -150,4 +155,76 @@ FileResourceStorage::exists( const char* key )
return !ec;
}

inline void
logger( const std::string& msg )
{
static std::mutex m;
std::lock_guard< std::mutex > lock( m );
printf( "%s\n", msg.c_str( ) );
}

inline void
FileResourceStorage::remove_resource( const char* resource_name, const char* expected_schema )
{
const std::string schema_name = std::string( resource_name ) + ".schema";
const bool resource_exists = exists( resource_name );
const bool schema_exists = exists( schema_name.c_str( ) );

if ( !resource_exists && !schema_exists )
{
logger( "[INFO] resource " + std::string( resource_name ) + ": does not exist" );
return;
}

if ( resource_exists ^ schema_exists )
{
// [CJ-TODO]
// remove what's left or simply return?
// can happen when crashes during writting
logger( "[ERR] resource " + std::string( resource_name ) + ": no schema or resource" );
}

auto schema = read_resource( ( schema_name.c_str( ) ) );
std::string stored_schema( reinterpret_cast< const char* >( schema.data( ) ),
schema.size_in_bytes( ) );

if ( stored_schema != expected_schema )
{
// [CJ-TODO]
// What if the schema change is intended?
logger( "[ERR] resource " + std::string( resource_name ) + ": unexpected schema" );
return;
}

boost::system::error_code ec_resource, ec_schema;
boost::filesystem::remove( get_path( resource_name ), ec_resource );
boost::filesystem::remove( get_path( schema_name.c_str( ) ), ec_schema );
if ( ec_resource.failed( ) )
{
logger( "[ERR] resource " + std::string( resource_name ) + ": failed to remove resource" );
}
else
{
logger( "[INFO] resource " + std::string( resource_name ) + ": removed resource" );
}
if ( ec_schema.failed( ) )
{
logger( "[ERR] resource " + std::string( resource_name ) + ": failed to remove schema" );
}
else
{
logger( "[INFO] resource " + std::string( resource_name ) + ": removed schema" );
}
}

inline void
FileResourceStorage::remove_multivector_index_resource( const char* resource_name,
const char* expected_schema )
{
std::string index_name = std::string( resource_name ) + internal::INDEX_SUFFIX;
std::string index_schema = internal::multivector_index_schema( expected_schema );

remove_resource( index_name.c_str( ), index_schema.c_str( ) );
}

} // namespace flatdata
15 changes: 15 additions & 0 deletions flatdata-cpp/include/flatdata/ResourceStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,21 @@ class ResourceStorage : private boost::noncopyable
*/
virtual bool exists( const char* key ) = 0;

virtual void
remove_resource( const char* /* resource_name */, const char* /* expected_schema */ )
{
// [CJ-TODO] make it pure virtual
return;
}

virtual void
remove_multivector_index_resource( const char* /* resource_name */,
const char* /* expected_schema */ )
{
// [CJ-TODO] make it pure virtual
return;
}

protected:
/**
* @brief Creates output stream for given key
Expand Down
7 changes: 7 additions & 0 deletions flatdata-cpp/src/ArchiveBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,11 @@ ArchiveBuilder::initialize( )
return static_cast< bool >( signature );
}

void
ArchiveBuilder::clean_up_signature( flatdata::ResourceStorage& storage )
{
const auto signature_name = internal::signature_name( name( ) );
storage.remove_resource( signature_name.c_str( ), schema( ) );
}

} // namespace flatdata
67 changes: 56 additions & 11 deletions flatdata-generator/flatdata/generator/templates/cpp/archive.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class {{ builder_name }} : public flatdata::ArchiveBuilder
{
public:
/// Creates Archive builder
static {{ builder_name }} open( std::shared_ptr< flatdata::ResourceStorage > storage );
static {{ builder_name }} open( std::shared_ptr< flatdata::ResourceStorage > storage, bool force_overwrite = false );
/// Archive schema
static const char* schema_definition( );

Expand All @@ -65,19 +65,22 @@ public: /// Resources
using {{ r|typedef_name }} = {{ resource.writer_type(r) }};
using {{ r|typedef_name("Reader") }} = {{ resource.reader_type(r) }};
{% if r|resource_provides_incremental_builder %}
{{ r|typedef_name }} start_{{ r.name }}( );
{{ r|typedef_name }} start_{{ r.name }}( bool force_overwrite = false );
{% endif %}
{% if r|provides_setter %}
bool set_{{ r.name }}( {{ r|typedef_name("Reader") }} data );
bool set_{{ r.name }}( {{ r|typedef_name("Reader") }} data, bool force_overwrite = false );
{% endif %}
void clean_up_{{ r.name }}( flatdata::ResourceStorage& storage );

{% endfor %}

{% for r in archive.resources|archive_resources %}
using {{ r|typedef_name }} = {{ resource.writer_type(r) }};
{{ r|typedef_name }}& {{ r.name }}( );
{{ r|typedef_name }}& {{ r.name }}( bool force_overwrite = false );
{% endfor %}

void clean_up( flatdata::ResourceStorage& storage );

private:
{{ builder_name }}( std::shared_ptr< flatdata::ResourceStorage > storage );

Expand Down Expand Up @@ -205,9 +208,13 @@ inline


inline {{ builder_name }}
{{ builder_name }}::open(std::shared_ptr< flatdata::ResourceStorage > storage )
{{ builder_name }}::open(std::shared_ptr< flatdata::ResourceStorage > storage, bool force_overwrite )
{
{{ builder_name }} result( storage );
if ( force_overwrite )
{
result.clean_up( *storage );
}
if ( !result.initialize( ) )
{
return {{ builder_name }}( );
Expand All @@ -217,31 +224,69 @@ inline {{ builder_name }}

{% for r in archive.resources|simple_resources %}
{% if r|resource_provides_incremental_builder %}
inline auto {{ builder_name }}::start_{{ r.name }}( ) -> {{ r|typedef_name }}
inline auto {{ builder_name }}::start_{{ r.name }}( bool force_overwrite ) -> {{ r|typedef_name }}
{
check_created( );
if ( force_overwrite )
{
clean_up_{{ r.name }}( storage( ) );
}
else
{
check_created( );
}
return storage( ).{{ resource.incremental_write_call(r) }}( "{{ r.name }}", internal::{{ archive.name }}__{{ r.name }}__schema__ );
}
{% endif %}
{% if r|provides_setter %}
inline bool
{{ builder_name }}::set_{{ r.name }}( {{ r|typedef_name("Reader") }} data )
{{ builder_name }}::set_{{ r.name }}( {{ r|typedef_name("Reader") }} data, bool force_overwrite )
{
check_created( );
if ( force_overwrite )
{
clean_up_{{ r.name }}( storage( ) );
}
else
{
check_created( );
}
return storage( ).write< {{ r|typedef_name("Reader") }} >( "{{ r.name }}", internal::{{ archive.name }}__{{ r.name }}__schema__, data );
}
{% endif %}
inline void
{{ builder_name }}::clean_up_{{ r.name }}( flatdata::ResourceStorage& storage )
{
storage.remove_resource( "{{ r.name }}", internal::{{ archive.name }}__{{ r.name }}__schema__ );
{% if r|is_multivector %}
storage.remove_multivector_index_resource( "{{ r.name }}", internal::{{ archive.name }}__{{ r.name }}__schema__ );
{% endif %}
}
{% endfor %}

{% for r in archive.resources|archive_resources %}
inline auto
{{ builder_name }}::{{ r.name }}( ) -> {{ r|typedef_name }}&
{{ builder_name }}::{{ r.name }}( bool force_overwrite ) -> {{ r|typedef_name }}&
{
if ( !m_{{ r.name }}.is_open( ) )
{
m_{{ r.name }} = {{ r|typedef_name }}::open( this->storage( ).create_directory( "{{ r.name }}" ) );
m_{{ r.name }} = {{ r|typedef_name }}::open( this->storage( ).create_directory( "{{ r.name }}" ), force_overwrite );
}
return m_{{ r.name }};
}
{% endfor %}

inline void
{{ builder_name }}::clean_up( flatdata::ResourceStorage& storage )
{
{% for r in archive.resources|simple_resources %}
clean_up_{{ r.name }}( storage );
{% endfor %}
{% for r in archive.resources|archive_resources %}
if ( auto subarchive_storage = storage.directory( "{{ r.name }}" ) )
{
m_{{ r.name }}.clean_up( *subarchive_storage );
}
{% endfor %}
clean_up_signature( storage );
}

{% endmacro %}