Pastey "dumping" a map demo
- Posted by ghaberek (admin) Feb 17, 2023
-- -- "dumping" a map demo -- https://openeuphoria.org/forum/137580.wc -- -- Here is an example of how to save and load objects on disk. The file format -- is incredibly simple: we just pretty_print() the key/value for each map on -- each line, and then read them back with get(). This creates a human-readable -- (and editable!) data storage format. Note that this method only supports -- nesting maps at a single level, such as users properties nested by user id. -- include std/get.e include std/map.e include std/pretty.e include std/filesys.e include std/error.e --** -- Extend the default pretty_print() format to print huamn -- readable strings and skip any newline/indent formatting. -- sequence PRETTY_INLINE = PRETTY_DEFAULT PRETTY_INLINE[DISPLAY_ASCII] = 2 -- print strings PRETTY_INLINE[LINE_BREAKS] = 0 -- no line breaks --** -- Store a sequence of maps by writing each as a sequence -- of key/value pairs, separated by newline. -- -- e.g. {{"key","value"},{"key","value},...} -- procedure save_maps( sequence file, sequence maps ) integer fn = open( file, "w" ) if fn = -1 then error:crash( "Could not write file: %s", {file} ) end if for i = 1 to length( maps ) do -- get the key/value pairs sequence data = map:pairs( maps[i] ) -- write object to disk pretty_print( fn, data, PRETTY_INLINE ) -- add a newline separator puts( fn, "\n" ) end for close( fn ) end procedure --** -- Load a sequence of maps by reading each key/value set -- from disk. -- function load_maps( object file ) integer fn = open( file, "r" ) if fn = -1 then error:crash( "Could not read file: %s", {file} ) end if sequence maps = {} while 1 do -- load an object from disk sequence result = stdget:get( fn ) -- result[1] could be: -- GET_SUCCESS - result[2] will be an object (yay!) -- GET_NOTHING - result[2] will be zero (so quit!) -- GET_EOF - result[2] will be zero (also quit!) -- GET_FAIL - crash with error message (boo!) if result[1] = GET_FAIL then error:crash( "get() failed!" ) end if if result[1] = GET_NOTHING or result[1] = GET_EOF then exit end if -- convert the key/value pairs to a map object data = map:new_from_kvpairs( result[2] ) -- add the map to the list maps = append( maps, data ) end while close( fn ) return maps end function --** -- Create several maps and store them all to a single file. -- procedure test_save( sequence file ) -- create several user objects map user1 = map:new() map:put( user1, "id", "abc123" ) map:put( user1, "name", "Alice" ) map user2 = map:new() map:put( user2, "id", "def456" ) map:put( user2, "name", "Bob" ) map user3 = map:new() map:put( user3, "id", "ghi789" ) map:put( user3, "name", "Carol" ) -- store each user in a "master" map using its id map users = map:new() map:put( users, map:get(user1,"id"), user1 ) map:put( users, map:get(user2,"id"), user2 ) map:put( users, map:get(user3,"id"), user3 ) -- demonstrate use of nested_put() to set values map:nested_put( users, {"abc123","email"}, "alice@example.com" ) map:nested_put( users, {"def456","email"}, "bob@example.com" ) map:nested_put( users, {"ghi789","email"}, "carol@example.com" ) -- get the maps stored in the master map and write them to disk save_maps( file, map:values(users) ) end procedure --** -- Read all the maps from disk and print their key/value pairs. -- procedure test_load( sequence file ) -- get the maps stored on disk sequence maps = load_maps( file ) -- store each user in the "master" map using its id map users = map:new() for i = 1 to length( maps ) do map:put( users, map:get(maps[i],"id"), maps[i] ) end for -- demonstrate use of nested_get() to get properties sequence alice_id = map:nested_get( users, {"abc123","id"} ) printf( 1, "Alice's id: \"%s\"\n", {alice_id} ) sequence bob_email = map:nested_get( users, {"def456","email"} ) printf( 1, "Bob's email: \"%s\"\n", {bob_email} ) sequence carol_name = map:nested_get( users, {"ghi789","name"} ) printf( 1, "Carol's name: \"%s\"\n", {carol_name} ) end procedure procedure main() sequence file = "users.map" if not file_exists( file ) then test_save( file ) end if test_load( file ) end procedure main()


