This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Noiro's profile picture

Database to file and back?

Started by Noiro, 12 April 2013 - 05:01 AM
Noiro #1
Posted 12 April 2013 - 07:01 AM
Any good example code on how you can save databases to a file and pull them out. Last time I tried, I ran into some serious parsing crap when the time came to read the data. Any ideas on how to do this?

Example of database:


lastX: 516
lastY: -214
lastZ: 72

This is less required, but is there any easy algorithms for basic encryption and decryption?
SadKingBilly #2
Posted 12 April 2013 - 07:19 AM
First, I would remove the spaces in the entries, as they're kind of pointless and make it slightly more difficult to read from the file. In order to read the entries, you'll need to use a string-split function. None exists currently (as far as I know), so you'll have to write one using string.sub(line, string.find(line, ":") or something like that.

Using that, you can simply iterate over every line in the file, checking for the entry you're looking for (again, with the string-split function), then saving the value to a variable.

(This may or may not be the best method. Either way, it works for me.)

As for encryption and decryption: pointless, since reading the code of a program is trivial. You'd be better off using a hash.
Noiro #3
Posted 12 April 2013 - 07:23 AM
First, I would remove the spaces in the entries, as they're kind of pointless and make it slightly more difficult to read from the file. In order to read the entries, you'll need to use a string-split function. None exists currently (as far as I know), so you'll have to write one using string.sub(line, string.find(line, ":") or something like that.

Using that, you can simply iterate over every line in the file, checking for the entry you're looking for (again, with the string-split function), then saving the value to a variable.

(This may or may not be the best method. Either way, it works for me.)

As for encryption and decryption: pointless, since reading the code of a program is trivial. You'd be better off using a hash.
So if I used:
string.sub(line, string.find(line, ":")
that would not split the string, it would merely remove the colon, yes? Would I have to iterate every letter on the line, save it to a table, find a colon, reiterate through the table and move everything before colon to a new table, build it back as a string, and save it as the variable, then rinse-repeat with the value of that variable?

o.O I thought lua was an easy language.
SadKingBilly #4
Posted 12 April 2013 - 07:31 AM
First, I would remove the spaces in the entries, as they're kind of pointless and make it slightly more difficult to read from the file. In order to read the entries, you'll need to use a string-split function. None exists currently (as far as I know), so you'll have to write one using string.sub(line, string.find(line, ":") or something like that.

Using that, you can simply iterate over every line in the file, checking for the entry you're looking for (again, with the string-split function), then saving the value to a variable.

(This may or may not be the best method. Either way, it works for me.)

As for encryption and decryption: pointless, since reading the code of a program is trivial. You'd be better off using a hash.
So if I used:
string.sub(line, string.find(line, ":")
that would not split the string, it would merely remove the colon, yes? Would I have to iterate every letter on the line, save it to a table, find a colon, reiterate through the table and move everything before colon to a new table, build it back as a string, and save it as the variable, then rinse-repeat with the value of that variable?

o.O I thought lua was an easy language.
string.find(string, mark) returns the first index of mark in string. So if you have a string "variable:value", then calling string("variable:value", ":") should return 9.
string.sub(string, pos) returns a substring of string where pos is the starting value. So if you call string.sub("variable:value", 10), you should get "value".
I think I might be off by a number or two, but that's the general idea for return the value of an entry.


file = fs.open("database", "r")
while true do
    line = fs.readLine()
    if string.sub(line, 1, string.find(line, ":")) == "lastZ" then
	    lastZ = string.sub(line.."", string.find(line, ":") + 1)
    end
end
The code might not work, but it's the general idea. Read the Lua documentation to learn more about string.sub() and string.find().
PixelToast #5
Posted 12 April 2013 - 07:34 AM
or just serialize a table:

--saving
tabletosavetofile={lastX=516,lastY=-214,lastZ=72}
file.write(textutils.serialize(tabletosavetofile))
--loading
tablereadfromfile=textutils.unserialize(file.readAll())
it would be WAAY easier
Noiro #6
Posted 12 April 2013 - 07:36 AM
or just serialize a table:

--saving
tabletosavetofile={lastX=516,lastY=-214,lastZ=72}
file.write(textutils.serialize(tabletosavetofile))
--loading
tablereadfromfile=textutils.unserialize(file.readAll())
it would be WAAY easier

Well, that is easy. :D/>
LordIkol #7
Posted 12 April 2013 - 07:36 AM
edit: hehe got ninjad and damn i forgot abour that serialize thing :D/>


local function saveSettings(s,l) -- s is the table with your information, l is the filename
  local file = fs.open(l, "w")  -- this opens a new file if exists overwrites it (look into the FS Api in the Wiki)
  if file then
for i=1, #s do  -- start a loop from one to number of entries in table s
		  file.writeLine(s[i]) write it to the file (FS Api again)
  end
	  file.close() -- close the file is very important
end
end

local function readSettings(l,s) -- l is the line you want to read s is the filename as string
local file = fs.open(l, "r") -- open file in read mode
  if file then
	log = {}  -- create table for your file
	local line = file.readLine()  -- set variable
	while line do
		  table.insert(log, line) -- add the lines from file to the table
		  line = file.readLine() --check the next line
	end
	file.close() -- close the file
return log[l] --return the line you need
  end
  end

use it like this (with your example data)



local lastpos = {516,-214,72} -- make sure x y z values are always in the same position of the table

saveSettings(lastpos,"lastcoords")
lastZ = readSettings(3,"lastcoords") -- read line 3 cause it contains the Z data

--or use it as function

local function getLastP()
lastX = readSettings(1,"lastcoords") -- read line 3 cause it contains the Z data
lastY = readSettings(2,"lastcoords") -- read line 3 cause it contains the Z data
lastZ = readSettings(3,"lastcoords") -- read line 3 cause it contains the Z data
end
SadKingBilly #8
Posted 12 April 2013 - 07:37 AM
Wooooooooooooooow. :blink:/> I'm an idiot. :(/>

Well, you learn something new every day! :lol:/> Thank you, PixelToast.
PixelToast #9
Posted 12 April 2013 - 07:40 AM
better reading function (more efficient):

function readPrefs(name,tf) -- reads data from a file
local file=fs.open(name,"r")
if not file then return false end
local dat
if tf then
  dat=file.readAll()
else
  dat=textutils.unserialize(file.readAll())
end
file.close()
return dat
end
from my api