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

FileSnipe -- precision file editing and database manager

Started by HDeffo, 13 February 2015 - 07:47 AM
HDeffo #1
Posted 13 February 2015 - 08:47 AM
An API for anyone who ever gets frustrated trying to use fs or io to adjust fine points in a file. Now you no longer need to worry about complex solutions to change only that middle line. This API was created to be as simple to use as possible while offering much functionality. That being said it is also my first program I have uploaded to the forums so its doubtfully "expert" however, I do ask that you give me a chance on this :P/>

As some added functionality this API can also use files to maintain persistent variables which you call like tables instead of a function so they 'feel' like normal variables. This way persistent variables can be more intuitive and written even by the newest of CC coders!

To get the API:
pastebin get JvAAnvAP


DOCUMENTATION
Spoiler

--#Documentation to use API
--#this all assumes you saved the file as "fileSnipe"

os.loadAPI("fileSnipe") --# in order to access the file you will need to load it first

file = fileSnipe.open(file [,mode][,debug]) --#file is the name of the file you want to edit or read, mode can be "d" for dynamic or "s" for singular defaults to singular if omitted.

--#in dynamic mode(d) fileSnipe will open and read the file every time you call to it, in singular(s) it will only read the file when first opened
--#only use dynamic mode if you have other computers or programs editing/accessing the same file

--#set debug to true to prevent the API from hiding the persistent variable comment block from editing
--#not recommended as this can cause many issues if done incorrectly

file.getLine(line) --# returns the file at line, if line is negative it will read from the end of the file up

--#if line is a table of numbers it will return a table containing all requested lines

file.setLine(line,data) --# changes the file at line to string data, if line is negative it will count lines from bottom up to

--#if line is 0 or less than -file:len() then itll write to the beginning of the file before other lines
--#if line would require the file to have more lines to reach that point it will add blank lines until the file has the requested line

file.getFile() --# returns the entire file as a table with each line a separate index in the table

file.setFile(data) --# sets the file equal to table data, each index in the table is a line in the file

file.len() --# returns the number of lines in the file

file.insert(line,data) --# adds a new line with string data to the file

--#if data is a table it will add all lines in the table into the file

file.remLine(line) --# removes line from the file

--#if line is a table of numbers will remove all lines in the table

file.find(string [,whole]) --# returns all instances of string in format {line,start}

--#if whole is true it will only find exact copies of the requested string otherwise it will also return words containing the string

file.swap(line1,line2) --# swaps two lines in the file

file.replace(oldString,newString,index [,whole]) --# replaces oldString with newString at occurrence index

--#if whole is true it will only replace exact copies of the requested string otherwise it will also return words containing the string

file.replaceAll(oldString,newString [,whole]) --# replaces all occurrences of oldString with newString

file.append(data) --# adds line (or lines if data is a table) data to the end of a file

file.combineLines(line1,line2 [,sep]) --# combines line1 and line2 in a file with sep between them

--# if sep is omitted defaults to " "

file.sepLines(line,point) --# separates one line into two at point

file.moveLine(start,end) --# moves a line to a new place in the file

file.concatLine(line,data) --# adds data to the end of line in the file

file.rawVar(variable) --#returns the raw equivalent of a saved persistent variable

--#only really useful for getting a saved function as the string code

file["example"] = "foo" --# how to set a variables

file["example"] = nil --# removing a variable

file["example"] = { type = "foo", } --# all variable types are supported

file["example"] = "function(str) print(str) end" --#accepts functions ( called with file["example"]() or file.example() )

file["example"] --# this will return whatever you have "example" defined as
(I am very very bad at explaining things so if anyone who is better at this would like to rewrite this documentation for me it would be very much appreciated)




Here is also a quick example program I whipped up merely to show the API in use
Spoiler

os.loadAPI("fileSnipe")
local name = fileSnipe.open("name")
local log = fileSnipe.open("history")
if not name["curr"] then
  log.setFile("om : 0")
  name["curr"] = "om"
end
print("Hello! You are "..name["curr"].." correct?")
print("(type y or n)")
local num = 0
local input = read()
if input == "y" then
  local line = log.find(name["curr"])
  local data = log.getLine(line[1][1])
  local num = data:sub(name["curr"]:len()+4,data:len())
  num = tonumber(num) + 1
  log.setLine(line[1][1],name["curr"].." : "..tostring(num))
  print("Welcome back "..name["curr"].."! I believe we have now talked "..tostring(num).." times before!")
elseif input == "n" then
  print("Oh my bad! What is your name then?")
  input = read()
  name["curr"] = input
  local line = log.find(name["curr"])
  if #line < 1 then
	log.append(name["curr"].." : 1")
	num = 1
  else
	local data = log.getLine(line[1][1])
	num = data:sub(name["curr"]:len()+3,data:len())
	num = tonumber(num) + 1
	log.setLine(line[1][1],name["curr"].." : "..tostring(num))
  end
  print("Well hello then "..name["curr"]..". I believe we have talked "..tostring(num).." times before.")
else
  print("I am sorry I did not understand that")
end

this program will remember the last name you gave it as well as save the number of times each name is given in a file named "history"



TODO list

*add support for persistent functions nested in persistent tables
*better handling for multi dimensional tables (currently file["tbl"]["foo"] = "bar" wont actually change the table)
*anything else anyone suggests in the comments
Edited on 09 March 2015 - 04:24 AM
MKlegoman357 #2
Posted 13 February 2015 - 01:50 PM
This is a very neat file API, with all these functions +1 for you! Good job!
Terminator_NL #3
Posted 13 February 2015 - 02:46 PM
Looks good! I'll be using this to snipe my files now! Keep up the good work
SpencerBeige #4
Posted 16 February 2015 - 04:20 PM
this is great! i am definatly downloading this. possibly putting it in a few of my world's roms; not many people have ever tried a better fs api
HDeffo #5
Posted 09 March 2015 - 05:17 AM
Only just realized I never uploaded the updated version of this code


changelog:

+added rawVar
+many functions now support several arguments or a table instead of only one
+persistent variables now play nice with existing data on a file so you can use them on the same file as the program
+now supports persistent functions
+functions now supported in non OOP format (e.g. file.getLine instead of file:getLine)
*several bugfixes and optimizations
-removed initVar as it is no longer needed or of any use
InternetUnexplorer #6
Posted 21 July 2015 - 04:51 PM
Hello,
I really like this API, I was just having a small problem and I cannot figure it out:

When I try this: (I am trying to delete the last line from the file.)


spath = fileSnipe.open("/TurtleGroups/path")
print(spath.len())
spath.remLine(spath.len())

I get this:
28
fileSnipe:137: bad argument: table expected, got nil

I have already verified that I can write to it earlier on in the program, but no matter what I try, passing it a table or changing the mode to dynamic, I can't figure it out.
I did put debug blocks in your code, and it stops when it tries to get the value of

self.fileMode
, because when I tried to print it for debugging at the beginning of the function, it stopped there. Unfortunately, that is all I know. Replies would be much appreciated!
Yarillo #7
Posted 21 July 2015 - 06:53 PM
Definetly going to use this ! Thanks.
InternetUnexplorer #8
Posted 22 July 2015 - 03:14 AM
Hello,
I really like this API, I was just having a small problem and I cannot figure it out:

When I try this: (I am trying to delete the last line from the file.)


spath = fileSnipe.open("/TurtleGroups/path")
print(spath.len())
spath.remLine(spath.len())

I get this:
28
fileSnipe:137: bad argument: table expected, got nil

I have already verified that I can write to it earlier on in the program, but no matter what I try, passing it a table or changing the mode to dynamic, I can't figure it out.
I did put debug blocks in your code, and it stops when it tries to get the value of

self.fileMode
, because when I tried to print it for debugging at the beginning of the function, it stopped there. Unfortunately, that is all I know. Replies would be much appreciated!
If anyone has any ideas on how to fix this, please help! Sorry for bumping.
MKlegoman357 #9
Posted 22 July 2015 - 09:38 AM
Hello,
I really like this API, I was just having a small problem and I cannot figure it out:

When I try this: (I am trying to delete the last line from the file.)


spath = fileSnipe.open("/TurtleGroups/path")
print(spath.len())
spath.remLine(spath.len())

I get this:
28
fileSnipe:137: bad argument: table expected, got nil

I have already verified that I can write to it earlier on in the program, but no matter what I try, passing it a table or changing the mode to dynamic, I can't figure it out.
I did put debug blocks in your code, and it stops when it tries to get the value of

self.fileMode
, because when I tried to print it for debugging at the beginning of the function, it stopped there. Unfortunately, that is all I know. Replies would be much appreciated!

The problem is that filesnipe expects 'table.sort()' to return a table, even though it does not. Since there is no license put on the program I've made a quick fix just for that particular problem. Try this:

pastebin get XQ0keKib filesnipe
Edited on 22 July 2015 - 07:39 AM
InternetUnexplorer #10
Posted 22 July 2015 - 04:20 PM
The problem is that filesnipe expects 'table.sort()' to return a table, even though it does not. Since there is no license put on the program I've made a quick fix just for that particular problem. Try this:

pastebin get XQ0keKib filesnipe

Thank you so much! I was completely out of ideas on how to fix it, so this really helped.