Pastey "dumping" a map demo
- Posted by ghaberek
(admin)
in February
--
-- "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()