Saving a table in file

classic Classic list List threaded Threaded
24 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Saving a table in file

Luciano de Souza

Hello,

Suppose we have the following table:

t =

{

{country = 'Brazil', city = 'São Paulo'},

{country = 'Italy', city = 'Napoli'},

{country = 'France', city = 'Nantes'},

{country = 'United States', city = 'Chicago'}

}

I know how to add or remove elements. But, how to save it in a file? With Luasql, I can save it, for example, in a Sqlite database. Using Luaxml, I can change it into string and save in a XML file.

I can't use file:wirte(t), because t should be a string.

Are there other ways to save a table into a file?

 

Luciano de Souza

Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Matthias Kluwe
Hi!

2010/3/7 Luciano de Souza <[hidden email]>:

> Hello,
>
> Suppose we have the following table:
>
> t =
>
> {
>
> {country = 'Brazil', city = 'São Paulo'},
>
> {country = 'Italy', city = 'Napoli'},
>
> {country = 'France', city = 'Nantes'},
>
> {country = 'United States', city = 'Chicago'}
>
> }
>
> I know how to add or remove elements. But, how to save it in a file?

Your problem is known as "serialization"
(http://en.wikipedia.org/wiki/Serialization, someone may add a Lua
example here). Take a look at http://www.lua.org/pil/12.1.html or
http://lua-users.org/wiki/TableSerialization.

Regards,
Matthias
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Luciano de Souza
If I understood: to serialize is to convert tables into a string
representation and, without some significant code, we cannot do it.

I will study everything you sent me. But now I need the simplest solution. I
am studying IUP. I am trying to save some data in a file to test more
realistically the features I programed. Up to now, the simplest way to save
tables, as I cold see, the way we write less lines, it seems to be using
XML. Am I right?

I only want to save a table. Firstly, I tried to use Sqlite3. I learnt the
SQL sintax. I read something about normalized databases. I read... I read...
But although Sqlite is really simple, something always is wrong. It seemed
to be very simple. But I got errors without error messages.

After I tried to use lots of coma separated files, but it became hard.

I tried to use XML and the results were OK to write values. To read values
semms to be a little bit harder. As I could see, the simplest way to store a
table is to use Luaxml.

Actually, I tried to create my tables in Pascal:

type

wolrd = record

country: string;

city: string;

end;

With Plua and the interface with Lua stack, I could add and remove values in
a table stored in a file. But it's a awful way, I know.

In Python, we have something like:

import shelve

file = shelve.open('countries.db')

For this point on, "file" can be used as a table. After trying so many
different things, only to save some data collected by a IUP interface,
perhaps I am impacient. I am not lazy, believe.

My options area:

1. to discover how to handle with the Sqlite erros;

2. to undestand better Luaxml. I found so few examples that I didn't mature
the idea. Lua has good manuals, but I think Luaxml is not one of then.

If I invest in this strategies of serialization, I will to learn more, and
more, and more... I know to learn is one of the best things in the wolrd,
but at this moment I need to conquer something.

That's the greatest problem of beginners. You are right in everything you
said. I think the problem is me.



----- Original Message -----
From: "Matthias Kluwe" <[hidden email]>
To: "Lua list" <[hidden email]>
Sent: Sunday, March 07, 2010 3:21 PM
Subject: Re: Saving a table in file


Hi!

2010/3/7 Luciano de Souza <[hidden email]>:

> Hello,
>
> Suppose we have the following table:
>
> t =
>
> {
>
> {country = 'Brazil', city = 'São Paulo'},
>
> {country = 'Italy', city = 'Napoli'},
>
> {country = 'France', city = 'Nantes'},
>
> {country = 'United States', city = 'Chicago'}
>
> }
>
> I know how to add or remove elements. But, how to save it in a file?

Your problem is known as "serialization"
(http://en.wikipedia.org/wiki/Serialization, someone may add a Lua
example here). Take a look at http://www.lua.org/pil/12.1.html or
http://lua-users.org/wiki/TableSerialization.

Regards,
Matthias

Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Natanael Copa
On 3/7/10, Luciano de Souza <[hidden email]> wrote:
> If I understood: to serialize is to convert tables into a string
> representation and, without some significant code, we cannot do it.

>
> I will study everything you sent me. But now I need the simplest solution. I
> am studying IUP. I am trying to save some data in a file to test more
> realistically the features I programed. Up to now, the simplest way to save
> tables, as I cold see, the way we write less lines, it seems to be using
> XML. Am I right?
>
> I only want to save a table. Firstly, I tried to use Sqlite3. I learnt the
> SQL sintax. I read something about normalized databases. I read... I read...
> But although Sqlite is really simple, something always is wrong. It seemed
> to be very simple. But I got errors without error messages.
>
> After I tried to use lots of coma separated files, but it became hard.
>
> I tried to use XML and the results were OK to write values. To read values
> semms to be a little bit harder. As I could see, the simplest way to store a
> table is to use Luaxml.
>
> Actually, I tried to create my tables in Pascal:
>
> type
>
> wolrd = record
>
> country: string;
>
> city: string;
>
> end;
>
> With Plua and the interface with Lua stack, I could add and remove values in
> a table stored in a file. But it's a awful way, I know.
>
> In Python, we have something like:
>
> import shelve
>
> file = shelve.open('countries.db')
>
> For this point on, "file" can be used as a table. After trying so many
> different things, only to save some data collected by a IUP interface,
> perhaps I am impacient. I am not lazy, believe.
>
> My options area:
>
> 1. to discover how to handle with the Sqlite erros;
>
> 2. to undestand better Luaxml. I found so few examples that I didn't mature
> the idea. Lua has good manuals, but I think Luaxml is not one of then.
>
> If I invest in this strategies of serialization, I will to learn more, and
> more, and more... I know to learn is one of the best things in the wolrd,
> but at this moment I need to conquer something.
>
> That's the greatest problem of beginners. You are right in everything you
> said. I think the problem is me.

If you you want serialization, save, and restore and xml is to
complex, then I'd go for one of those json libraries (for example
json4lua)

require("json")
t = {
-- data here
}

-- save to file
f = io.open(filename, "w")
f:write(json.encode(t))
f:close()

--read from file
f = io.open(filename)
t = json.decode(f:read("*all"))
f:close()
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Nevin Flanagan
In reply to this post by Luciano de Souza
One way to serialize tables in Lua is to write the actual table constructor text into the file. This has the advantage that you can then use Lua itself to load the table from the file contents.

This is a simplified version that does not handle nested tables:

function table.pickle(t, fileName)
local output = io.open(fileName, "w")
output:write("return {\n")
for k, v in pairs(t) do
if (type(k) == 'string' or type(k) == 'number' or type(k) == 'boolean') 
and (type(v) == 'string' or type(v) == 'number' or type(v) == 'boolean'') then
if type(k) == 'string' then 
k = string.format("%q", k)
else
k = tostring(k)
end
if type(v) == 'string' then
v = string.format("%q", v)
else
v = tostring(v)
end
output:write(string.format("[%s] = %s,\n", k, v)
end
end
output:close()
end


NFF
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Andre Leiradella
This version handles nested tables: http://lua-users.org/wiki/PickleTable

Cheers,

Andre

On 07/03/2010 17:25, Nevin Flanagan wrote:
One way to serialize tables in Lua is to write the actual table constructor text into the file. This has the advantage that you can then use Lua itself to load the table from the file contents.

This is a simplified version that does not handle nested tables:

function table.pickle(t, fileName)
local output = io.open(fileName, "w")
output:write("return {\n")
for k, v in pairs(t) do
if (type(k) == 'string' or type(k) == 'number' or type(k) == 'boolean') 
and (type(v) == 'string' or type(v) == 'number' or type(v) == 'boolean'') then
if type(k) == 'string' then 
k = string.format("%q", k)
else
k = tostring(k)
end
if type(v) == 'string' then
v = string.format("%q", v)
else
v = tostring(v)
end
output:write(string.format("[%s] = %s,\n", k, v)
end
end
output:close()
end


NFF

Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Petite Abeille
In reply to this post by Luciano de Souza

On Mar 7, 2010, at 7:09 PM, Luciano de Souza wrote:

> But, how to save it in a file?

As mentioned, you need to serialize (i.e. create a string representation) your table.

For example:

local Data = require( 'Data' )

-- save the content of table 't' to file 't.txt'
Data[ 't.txt' ] = t

-- load the content of file 't.txt' into variable 't'

t = Data[ 't.txt' ]

-- print the content of table 't' as a string
print( Data( t ) )

_[1]={}
_[1]["city"]="São Paulo"
_[1]["country"]="Brazil"
_[2]={}
_[2]["city"]="Napoli"
_[2]["country"]="Italy"
_[3]={}
_[3]["city"]="Nantes"
_[3]["country"]="France"
_[4]={}
_[4]["city"]="Chicago"
_[4]["country"]="United States"






Data.lua (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

joao lobato
In reply to this post by Andre Leiradella
This one is http://www.lua.org/pil/12.1.html generalized to accept
tables as indices as well as values; the save function gives you a
string representation of your table that you can load using loadstring
or loadfile. I don't recall how much testing I did regarding function
environments but they're disabled by default.

On 3/7/10, Andre Leiradella <[hidden email]> wrote:

> This version handles nested tables: http://lua-users.org/wiki/PickleTable
>
> Cheers,
>
> Andre
>
> On 07/03/2010 17:25, Nevin Flanagan wrote:
>> One way to serialize tables in Lua is to write the actual table
>> constructor text into the file. This has the advantage that you can
>> then use Lua itself to load the table from the file contents.
>>
>> This is a simplified version that does not handle nested tables:
>>
>> function table.pickle(t, fileName)
>> local output = io.open(fileName, "w")
>> output:write("return {\n")
>> for k, v in pairs(t) do
>> if (type(k) == 'string' or type(k) == 'number' or type(k) == 'boolean')
>> and (type(v) == 'string' or type(v) == 'number' or type(v) ==
>> 'boolean'') then
>> if type(k) == 'string' then
>> k = string.format("%q", k)
>> else
>> k = tostring(k)
>> end
>> if type(v) == 'string' then
>> v = string.format("%q", v)
>> else
>> v = tostring(v)
>> end
>> output:write(string.format("[%s] = %s,\n", k, v)
>> end
>> end
>> output:close()
>> end
>>
>>
>> NFF
>
>

serialize.lua (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Luciano de Souza
In reply to this post by Petite Abeille
Wonderful! It's really wonderful. When I mentioned I would like something
really simple, I could not imagine how simple it would be! With Data e Json,
I could do everything I wanted.

I always admire Python for the simpliicity. For the same reason, I admire
Lua. I have started in Lua because of IUP. Now I can't imagine to adopt
another language.

A gift... What you sent me was a gift.

There is choices more complicated, adopted by people I respect. But I am
sure that for my simple needs, Data and Json are perfect. Both are excelent.

Thank you!



----- Original Message -----
From: "Petite Abeille" <[hidden email]>
To: "Lua list" <[hidden email]>
Sent: Sunday, March 07, 2010 5:54 PM
Subject: Re: Saving a table in file



On Mar 7, 2010, at 7:09 PM, Luciano de Souza wrote:

> But, how to save it in a file?

As mentioned, you need to serialize (i.e. create a string representation)
your table.

For example:

local Data = require( 'Data' )

-- save the content of table 't' to file 't.txt'
Data[ 't.txt' ] = t

-- load the content of file 't.txt' into variable 't'

t = Data[ 't.txt' ]

-- print the content of table 't' as a string
print( Data( t ) )

_[1]={}
_[1]["city"]="São Paulo"
_[1]["country"]="Brazil"
_[2]={}
_[2]["city"]="Napoli"
_[2]["country"]="Italy"
_[3]={}
_[3]["city"]="Nantes"
_[3]["country"]="France"
_[4]={}
_[4]["city"]="Chicago"
_[4]["country"]="United States"





--------------------------------------------------------------------------------


>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Luciano de Souza
In reply to this post by joao lobato
I haven't seen your message before. Thank you. I need to take a look more
carefully to understand the usage of this library.
I am really impressed about the number of relevant modules are available.
Up to now, I only leaded with the standard libraries.

----- Original Message -----
From: "joao lobato" <[hidden email]>
To: "Lua list" <[hidden email]>
Sent: Sunday, March 07, 2010 6:12 PM
Subject: Re: Saving a table in file


> This one is http://www.lua.org/pil/12.1.html generalized to accept
> tables as indices as well as values; the save function gives you a
> string representation of your table that you can load using loadstring
> or loadfile. I don't recall how much testing I did regarding function
> environments but they're disabled by default.
>
> On 3/7/10, Andre Leiradella <[hidden email]> wrote:
>> This version handles nested tables: http://lua-users.org/wiki/PickleTable
>>
>> Cheers,
>>
>> Andre
>>
>> On 07/03/2010 17:25, Nevin Flanagan wrote:
>>> One way to serialize tables in Lua is to write the actual table
>>> constructor text into the file. This has the advantage that you can
>>> then use Lua itself to load the table from the file contents.
>>>
>>> This is a simplified version that does not handle nested tables:
>>>
>>> function table.pickle(t, fileName)
>>> local output = io.open(fileName, "w")
>>> output:write("return {\n")
>>> for k, v in pairs(t) do
>>> if (type(k) == 'string' or type(k) == 'number' or type(k) == 'boolean')
>>> and (type(v) == 'string' or type(v) == 'number' or type(v) ==
>>> 'boolean'') then
>>> if type(k) == 'string' then
>>> k = string.format("%q", k)
>>> else
>>> k = tostring(k)
>>> end
>>> if type(v) == 'string' then
>>> v = string.format("%q", v)
>>> else
>>> v = tostring(v)
>>> end
>>> output:write(string.format("[%s] = %s,\n", k, v)
>>> end
>>> end
>>> output:close()
>>> end
>>>
>>>
>>> NFF
>>
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Doug Rogers-3
In reply to this post by Petite Abeille
Petite Abeille wrote:
> local Data = require( 'Data' )
> -- save the content of table 't' to file 't.txt'
> Data[ 't.txt' ] = t
> -- load the content of file 't.txt' into variable 't'
> t = Data[ 't.txt' ]

Wow, that's one crazy looking interface! Why bother with encode(t/s),
write(file, t) or read(file) when you can use __call, __index and
__newindex!

It reminds me of the gyrations I went through when I discovered all the
amusing ways to use C++ operator overloading. Lots of fun! Heck, in C++
some of it became part of std::.

Other than the obvious fun, though, is there a benefit I've missed to
having the implementation use __call, __index, and __newindex? The
indexing doesn't make me think "writing/reading a file". Why not just
use two named functions for the API? Brevity? Couldn't that also be
achieved with local tread = data.read?

Just curious.

Doug
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Tony Finch
On Sun, 7 Mar 2010, Doug Rogers wrote:
>
> Why not just use two named functions for the API?

You only need one function, since you can use loadstring() to deserialize.

Tony.
--
f.anthony.n.finch  <[hidden email]>  http://dotat.at/
GERMAN BIGHT HUMBER: SOUTHWEST 5 TO 7. MODERATE OR ROUGH. SQUALLY SHOWERS.
MODERATE OR GOOD.

serialize.lua (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Petite Abeille
In reply to this post by Doug Rogers-3

On Mar 8, 2010, at 12:49 AM, Doug Rogers wrote:

> Wow, that's one crazy looking interface! Why bother with encode(t/s), write(file, t) or read(file) when you can use __call, __index and __newindex!

If you liked the above, you will positively love the following:

local DB = require( 'DB' )
local aDB = DB( 'sqlite3://localhost/test.db' )

for aContact in aDB( 'select * from contact' ) do
    print( aContact.name, aContact.email )
end

http://dev.alt.textdrive.com/browser/HTTP/DB.lua

For reference, the plain LuaSQL equivalent:

require "luasql.postgres"
env = assert (luasql.postgres())
con = assert (env:connect("luasql-test"))
cur = assert (con:execute"SELECT name, email from people")
row = cur:fetch ({}, "a")
while row do
  print(string.format("Name: %s, E-mail: %s", row.name, row.email))
  row = cur:fetch (row, "a")
end

Another inspirational example, a bare bone HTTP server:

local HTTP = require( 'HTTP' )
local TCPServer = require( 'TCPServer' )

local aServer = TCPServer( '127.0.0.1', 1080 )

HTTP[ '/' ] = function() return 'Hello world' end

aServer( HTTP )

> It reminds me of the gyrations I went through when I discovered all the amusing ways to use C++ operator overloading. Lots of fun! Heck, in C++ some of it became part of std::.
>
> Other than the obvious fun, though, is there a benefit I've missed to having the implementation use __call, __index, and __newindex? The indexing doesn't make me think "writing/reading a file". Why not just use two named functions for the API? Brevity? Couldn't that also be achieved with local tread = data.read?
>
> Just curious.

I would blame Rici Lake's FuncTable for the initial inspiration:

http://lua-users.org/wiki/FuncTables

Went downhill from there: how would it look like to not use verbs and instead limit oneself to Lua's basic table operators. In short, few verbs, many names.

For your viewing delight, here is the result of all that handy work:

http://dev.alt.textdrive.com/browser/HTTP



Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Petite Abeille
In reply to this post by Tony Finch

On Mar 8, 2010, at 5:07 PM, Tony Finch wrote:

> You only need one function, since you can use loadstring() to deserialize.
>
> <serialize.lua>

Ohhhhh, nice :)

Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Miles Bader-2
In reply to this post by Petite Abeille
Petite Abeille <[hidden email]> writes:
> http://dev.alt.textdrive.com/browser/HTTP

WTF do they prefix every variable with "a" though?

-Miles

--
Genealogy, n. An account of one's descent from an ancestor who did not
particularly care to trace his own.
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Doug Rogers-3
In reply to this post by Petite Abeille
Petite Abeille wrote:
> If you liked the above, you will positively love the following:
> local DB = require( 'DB' )
> local aDB = DB( 'sqlite3://localhost/test.db' )
> for aContact in aDB( 'select * from contact' ) do
>     print( aContact.name, aContact.email )
> end

I do indeed find that attractive. But notice how it doesn't use indexing
for function invocation. That's the weird part about the Data module, at
least it is weird for me.

> Another inspirational example, a bare bone HTTP server:
> local HTTP = require( 'HTTP' )
> local TCPServer = require( 'TCPServer' )
> local aServer = TCPServer( '127.0.0.1', 1080 )
> HTTP[ '/' ] = function() return 'Hello world' end
> aServer( HTTP )

All except the HTTP['/'], which I assume sets code to run when a URL
gives just the host name with a '/' after it. I guess I can see that as
a form of indexing, in a way. And in that way maybe I can get my brain
to see Data['file.lua'] = t to be some sort of indexing. The latter will
take a bit longer!

> I would blame Rici Lake's FuncTable for the initial inspiration:
> http://lua-users.org/wiki/FuncTables

Another fun piece of Lua application that I have visited before. I think
the wiki page should be /Functables (without a capital T).

> For your viewing delight, here is the result of all that handy work:
> http://dev.alt.textdrive.com/browser/HTTP

Yes, I've played around with Nanoki. I like it. It was quite simple to
set up my own little http playpen. That was some years ago and I haven't
had the need since. That might be changing here in the future. The thing
I loved about Nanoki was its tiny size and its understandability.

Doug
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Tony Finch
In reply to this post by Miles Bader-2
On Tue, 9 Mar 2010, Miles Bader wrote:
>
> WTF do they prefix every variable with "a" though?

It's hungarian notation for dynamic languages :-)

Tony.
--
f.anthony.n.finch  <[hidden email]>  http://dotat.at/
GERMAN BIGHT HUMBER: SOUTHWEST 5 TO 7. MODERATE OR ROUGH. SQUALLY SHOWERS.
MODERATE OR GOOD.
Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Petite Abeille

On Mar 9, 2010, at 2:32 PM, Tony Finch wrote:

>> WTF do they prefix every variable with "a" though?
>
> It's hungarian notation for dynamic languages :-)

:P

A naming convention I picked back in my obj-c days:

http://cocoadevcentral.com/articles/000083.php#7

E.g.:

-- archetype, class, module, etc
local DB = require( 'DB' )

-- specific instance
local aDB = DB( 'sqlite://' )

Of course, one could argue that an expressive one letter code such as, hmmm, let me think, 'd' would be plentiful enough to fully express the meaning, complexity and nuances of such a variable... but... to each his own... des goûts et des couleurs, on ne discute pas.







Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

spir ☣
On Tue, 9 Mar 2010 19:22:01 +0100
Petite Abeille <[hidden email]> wrote:

> -- archetype, class, module, etc
> local DB = require( 'DB' )
>
> -- specific instance
> local aDB = DB( 'sqlite://' )
>

FWIW: I found this convention fully self-understanding in your code samples.

Denis
--
________________________________

la vita e estrany

spir.wikidot.com

Reply | Threaded
Open this post in threaded view
|

Re: Saving a table in file

Philippe Lhoste
In reply to this post by Petite Abeille
On 09/03/2010 19:22, Petite Abeille wrote:

> A naming convention I picked back in my obj-c days:
>
> http://cocoadevcentral.com/articles/000083.php#7
>
> E.g.:
>
> -- archetype, class, module, etc
> local DB = require( 'DB' )
>
> -- specific instance
> local aDB = DB( 'sqlite://' )

At my work, they kept the habit from MSVC days to prefix, in Java, object instance by the
abbreviation of the class name, eg. ArrayList instance would be alCustomers and so on.
Bad or not (bad when you meet a vCustomer array list because it was a Vector...), that's
the local rule.
Some people were lazy and just use a and the prefixes: aCustomer, anIterator, theManager
Which I find even more atrocious than the Hungarian notation...
That, and the overused myXxx...
At least, the office rule conveys some useful information (although it can be outdated if
refactoring isn't properly done), while the Cocoa convention you show (I just see they set
that as a common convention) and the habit developed (independently) by my co-workers,
just tend to make all the variables looking the same and hinder readability.

Oh, well, that's better than the toto, titi, tata variables French programmers use often
when they lack imagination, not unlike foo, bar, baz...
At least I prefer ga, bu, zo, meuh... :-P

--
Philippe Lhoste
--  (near) Paris -- France
--  http://Phi.Lho.free.fr
--  --  --  --  --  --  --  --  --  --  --  --  --  --

12