Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Problem io.open "Permission denied"
Started by J@V0 Dec 16 2018 11:50 AM

- - - - -
6 replies to this topic
permission denied files

Best Answer J@V0 , 30 December 2018 - 01:54 AM

It looks like the problem is fixed by adding globalData.query = nil in M.confirmAction() after line 2.

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

J@V0

[GLOBAL: userInfoPane.html]
J@V0
  • Enthusiast

  • 43 posts
  • Corona SDK

Up to now, I was saving some information in a database file (using sqlite3) when my user was adding a new building.to the map. My code was:

 

game.lua:

addBuildingToDatabase = function (buildingId, x, y, currentPopulation)
  databaseModuleVar.openDatabase("currentGame.db", system.DocumentsDirectory)
  local insertQuery = [[INSERT INTO buildings VALUES ( NULL, "]] .. buildingId .. [[","]] .. x .. [[","]] .. y .. [[","]] .. currentPopulation .. [[" );]]
  globalData.db:exec(insertQuery)
  return true
end

After that, the user could manually save the current progress in a new file:

copyDBto.lua

function M.copyDatabaseTo( filename, destination )
  
-- If the database is opened, close it
if (globalData.db ~= nil and globalData.db:isopen()) then
  print("DB IS OPEN")
  globalData.db:close()
else
  print("DB IS NOT OPEN")
end

    assert( type(filename) == "string", "string expected for the first parameter but got " .. type(filename) .. " instead." )
    assert( type(destination) == "table", "table expected for the second paramter but bot " .. type(destination) .. " instead." )
    local sourceDBpath = system.pathForFile( filename, system.DocumentsDirectory )

    local readHandle, errorString = io.open( sourceDBpath, "rb" )

    assert( readHandle, "Database at " .. filename .. " could not be read from system.DocumentsDirectory: " )
    assert( type(destination.filename) == "string", "filename should be a string, its a " .. type(destination.filename) )
    assert( type(destination.baseDir) == "userdata", "baseName should be a valid system directory" )
 
    local destinationDBpath = system.pathForFile( destination.filename, destination.baseDir )
    local writeHandle, writeErrorString = io.open( destinationDBpath, "wb" )
    assert( writeHandle, "Could not open " .. destination.filename .. " for writing." )
 
    local contents = readHandle:read( "*a" )
    writeHandle:write( contents )
 
    io.close( writeHandle )
    io.close( readHandle )
    return true
end

I have recently changed my game.lua so that the changes are not written into the database directly, only after the user has tapped a Confirm button. The new code is the following:

 

game.lua:

addBuildingToDatabase = function (buildingId, x, y, currentPopulation)

  databaseModuleVar.openDatabase("currentGame.db", system.DocumentsDirectory)
  globalData.query = {}
  globalData.query = globalData.db:prepare[[INSERT INTO buildings (buildingId, x, y, currentPopulation) VALUES(:p_buildingId, :p_x, :p_y, :p_currentPopulation)]]
  globalData.query:bind_names({p_buildingId=buildingId, p_x=x, p_y=y, p_currentPopulation=currentPopulation})
  return true
end

Confirm action:

function M.confirmAction() 
  globalData.query:step()
  --globalData.db:close()
  M.resetToolbarsAndButtons()
  M.stopRunningOtherEvents()
end

Unfortunately when doing so, the program crashes and complains about Permissions denied (line 15) when accessing the file to save in copyDBto.lua

 

It's not a problem with the folder permissions or the directory because that part worked before. I believe it has something to do with the new code, maybe the file is still open? However I check if the database is open in copyDatabaseTo but it does not enter the loop line 4.

 

ANy idea what could be wrong?



[TOPIC: post.html]
#2

J@V0

[GLOBAL: userInfoPane.html]
J@V0
  • Enthusiast

  • 43 posts
  • Corona SDK

I'm still stuck with this problem. Even if I uncomment --globalData.db:close() line 3 of the confirmAction function, I get Permission Denied.

I have run multiple tests and narrowed down that the issue is because I wrote in the database (in addBuildingToDatabase ) and the file seems to be in use.

Unfortunately closing the database does not help and I verified that the file was not opened with io.open



[TOPIC: post.html]
#3

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,541 posts
  • Enterprise

I don't see where you're opening the database. I also don't have a good idea on how you're database creation, operating actions, etc. are flowing.

 

Since you're writing to the database, there are generally two scenarios, either on first time running you 

 

1. copy a pre-built database from system.ResourceDirectory to system.DocumentsDirectory and open the database in system.DocumentsDirectory.

 

2. create a new database in system.DocumentsDirectory, create the initial tables, and run any initial queries to start the user out.

 

after that, your app should either open, create, read, update, delete records, and close on each action, or open on app startup, leave it open while the app runs and then close when the app shuts down. You could alternately close on suspend and open again on resume.

 

Rob



[TOPIC: post.html]
#4

J@V0

[GLOBAL: userInfoPane.html]
J@V0
  • Enthusiast

  • 43 posts
  • Corona SDK

Do I need to close the database file if I want to read the same file with io.open "rb" ?

[TOPIC: post.html]
#5

Rob Miracle

[GLOBAL: userInfoPane.html]
Rob Miracle
  • Moderator

  • 25,541 posts
  • Enterprise

Yes



[TOPIC: post.html]
#6

J@V0

[GLOBAL: userInfoPane.html]
J@V0
  • Enthusiast

  • 43 posts
  • Corona SDK

When I add globalData.db:close() before the io.open, the following error occur:

calling 'close' on bad self (attempt to use closed sqlite database)

So I guess the connection to the database is already closed.

 

I also tried io.type( readHandle ) after line 15 of copyDBto.lua and it returns nil.

 

How can I see if the file is used by anything? Or can I free it up from previous usage?

 

By the way, I am using alternative 1 that you mentioned above and that works fine until the described step. Entries are correctly added to my database.

 

I can try to provide a better code sample if none is able to answer my questions above or if it still doesn't help.

 

Thanks for the help!

/J@V0



[TOPIC: post.html]
#7

J@V0

[GLOBAL: userInfoPane.html]
J@V0
  • Enthusiast

  • 43 posts
  • Corona SDK

  Best Answer

It looks like the problem is fixed by adding globalData.query = nil in M.confirmAction() after line 2.




[topic_controls]
[/topic_controls]

Also tagged with one or more of these keywords: permission denied, files