Read and write the same file

I add it to string.lua and it works like you said. But, I wonder why it can’t block alphabetic characters ?

Ok.
Referring to online documentation, I see that there is no string for alphabetic characters. So I have to do it from the beginning in native.newTextField() with object.inputType. I don’t like it, but I have no other choice.

in your past reply you said " I can create a scene and print the users to the screen" can you send me an example

re: Blocking

I’m confused. I thought you wanted to allow

  • alpha - abcdABCD…
  • numeric - 01234…

, but ‘block’ all else.

While you can’t block key inputs, you can detect when users type them and remove them from the text string, which is effectively the same thing.

Note: object.inputType is for selecting/setting the keyboard type, not blocking inputs.

Re: example of new scene for dumping .
Sorry I don’t have the time to do that right now. Try taking a look at one of the GUI examples that comes with the simulator and/or these docs here:

Scrollview:

Scenes:

I’m very late to this particular party, but I’m just here to chime in regarding Lua’s io library:

What you can do to a file and how you can do it depends on how you access it via io.open(). You can open it for reading only or writing only, or you can open it for both reading and writing, etc.

Also, regarding the question of numeric, alphabetic, alphanumeric, etc. characters in Lua. It’ll be a lot easier and significantly faster to just use pattern matching:

https://www.lua.org/pil/20.2.html

For instance, if you want to ensure that a string contains only numbers, you can check it via:

local myString = "Hello World"
print( string.match(myString, "%D") ) -- prints "H"

Since string.match didn’t return nil, we know that there are non-numbers in the string. You can easily extend the pattern matching to fit all sorts of scenarios.

1 Like

hello dear friend I would like to use this function to display only the last user but I don’t know how to do it.

function m.printUsers()
   for i = 1, #m._userDB do
      print( "User #" .. i )
   end
end

by the way I try to show the userDB.txt to screen by using Scroll view . it show all the file. I dont know how to select the content line on the file to view. for example I want to show only user name, but it show me everything " username, password and so…"

Won’t work if index > # of users

function m.printUserNameByIndex( index )
   print( "User # " .. index .. " == "  .. m._userDB[index] )
end

Won’t work if no users in DB

function m.printLastUserName( )
   print( "Last User == " .. m._userDB[#m._userDB] )
end

I hacked a ugly example together.

Read the two steps in main.lua and follow those directions to run this example.

You’ll have to take this starting point and adjust it for your on use.

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2022/05/fileIO_userDB_example4_scrollview.zip

Hi !
I am working on your function some step works but I still don’t know to use some others.
for example I want to add the # of the last user in two different databases and display the result on the screen.
I mean in the UsersDB1.txt the name John is the # 9 and in the UsersDB2.txt the name peter is the # 30 . I would like to do

9+30=39 then display 39 at the screen.

I’m having trouble understanding your questions. Please spend more time formatting them for legibility and clarity.

Also, I suggest you temporarily stop work on your app. Instead, make yourself a very basic (NO GUI) testbench.

It should only include:

  1. The latest copy of the extension scripts.
  2. The latest copy of the DB module.
  3. main.lua

Then, in main.lua just play around with the DB module and extensions:

  • manually adding users,
  • changing your code,
  • re-running,
  • dumping the users to the console,

Keep doing this till you fully understand how the extensions and modules work. You will probably find that you need to modify and/or add new functions in the DB module.

Once you have a complete understanding of the extensions/modules you can address the app.

Lastly, I will only be able answer specific questions with an example I can download and run demonstrating the problem you’re stuck on. I’ve got a full time job and do this in my spare time. So, while I like to help out I have to be careful or I’ll get no work done on my own games.

I understood and followed your advice. I studied the modules and found the answer to many questions. But there is one that I still haven’t understood. how to remove a user using : user_db_module.removeRecordByReference( userid, password )

You can accomplish removing a user by ‘name’ + ‘pasword’ using this code:

-- Following code assumes you have already stored the name and password to remove in local variables named 'user_name' and 'user_password'
--
local rec = user_db_module.getRecordByUserID( user_name )
if ( rec ) then
    if (  rec.password == user_password ) then
        user_db_module.getRecordByUserID( rec )
       -- you could print a message here indicating success
    else
        -- you could print a message here indicating failure: WRONG PASSWORD
    end
else 
  -- you could print a message here indicating failure: USER NOT FOUND
end

Alternately, you could use existing methods in the module to write a new one:

function m.removeRecordByNamePass( name, password )
    local rec = m.getRecordByUserName( name )
    if ( not rec ) then
        return false, "no such user"
    end

    if (  rec.password == password ) then
        m.removeRecordByReference( rec )
        return true, ""
    end

    return false, "wrong password"
end

Later call it like thisl

local success, reason = user_db_module.removeRecordByNamePass( user_name, user_pass )
if(  success ) then
     print( "User " .. user_name .. " record successfully removed" )
else
     print( "User " .. user_name .. " record not removed.  Reason: " .. reason  )
end

Thanks for your answer, but it doesn’t work. I tried with:
function m.removeRecordByReference( rec ).
it removed the last user regardless of the name entered in the box. it seems that the
function table.removeByRef(t, obj) is incorrectly referenced.

Why would removeRecordByReference() be called without you first checking that the name matches?

That is not what I did in both examples.

The steps are:

  • Try to get a record by name.
  • If the record returned is nil, abort
  • If the record is not nil, the name matches.
  • Check that the record.password matches the one you want to delete.
  • If it does, then delete the record.
  • If it does not, abort.

Everything you need is in the examples above and the module provided.

If you can’t get this working, provide a copy of your modified ‘DB’ module so I can see what your code is doing.

I suggest doing all of the lookup, deletion, etc in the module.

I made one final example.

I added all the features I think a basic userDB module would need and tested them all in main.lua

There are no GUIs in this example. There is only test code showing how to use/call the module methods.

https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2022/06/userDB.zip

user_db_module.lua

-- =============================================================
-- Example 'user db' management module.  Add and change functions as needed.
-- =============================================================
local m = {}


-- Called once on start up to load existing user DB if any exists
-- If file does not exist yet, DB == {} by end of function
function m.init()
   m._userDB = table.load("userDB.txt") or {}
end

-- Function demonstrating how to iterate over user DB list and do something with it. (In this case print it to the console.)
function m.printUsers()
   for i = 1, #m._userDB do
      print( "User #" .. i )
      print( " > Name: " .. m._userDB[i].name )
      print( " > Password: "   .. m._userDB[i].password )
   end
end

function m.getRecordCount( )
   return #m._userDB
end

function m.getRecordByIndex( index )
   if( m._userDB[index] ) then
      return m._userDB[index]
   else 
      print( "Warning: getByIndex(), invalid index " .. index )
      return nil
   end
end

function m.removeRecordByReference( rec )
   table.removeByRef( m._userDB, rec )
   table.save( m._userDB, "userDB.txt" )
end

function m.getRecordByUserName( name )
   for i = 1, #m._userDB do
      -- print( i, name, m._userDB[i], m._userDB[i].name,  m._userDB[i].password, name == m._userDB[i].name )
      if( name == m._userDB[i].name ) then 
         return m._userDB[i]
      end
   end
   return nil
end

function m.nameExists( name )
   for i = 1, #m._userDB do
      -- print( i, name, m._userDB[i], m._userDB[i].name,  m._userDB[i].password, name == m._userDB[i].name )
      if( name == m._userDB[i].name ) then 
         return true
      end
   end
   return false
end

function m.addUser( name, password )
   local record = { name = name, password = password }
   if( not m.nameExists(name) ) then
      table.insert(m._userDB, record )
      table.save( m._userDB, "userDB.txt" )
      return true, "user record added"
   end
   return false, "username exists already"
end

function m.removeRecordByNamePass( name, password )
    local rec = m.getRecordByUserName( name )
    if ( not rec ) then
        return false, "no such user"
    end

    if (  rec.password == password ) then
        m.removeRecordByReference( rec )
        return true, ""
    end

    return false, "wrong password"
end


return m

main.lua

io.output():setvbuf("no")
display.setStatusBar(display.HiddenStatusBar)
-- =====================================================
-- Require these just once in main.lua
require "extensions.string"
require "extensions.io"
require "extensions.table"
require "extensions.math"
require "extensions.display"
local user_db_module = require "user_db_module"
user_db_module.init() 
-- =====================================================
-- Example usage of functions in module.
-- =====================================================
-- 
print( " ******************* EXAMPLE STARTED RUNNING ")

--
print( "\n *******************  ")
print( "Users in DB " .. tostring( user_db_module.getRecordCount() ) )
user_db_module.printUsers() 

--
print( "\n *******************  ")
local success
local reason

success, reason = user_db_module.addUser( "Bob", "mypass123" )
print( success, reason )

success, reason = user_db_module.addUser( "Sue", "mypass456" )
print( success, reason )

success, reason  = user_db_module.addUser( "Bob", "mypass789" )
print( success, reason )

user_db_module.printUsers() 


--
print( "\n *******************  ")
local function test_find( name )
	local rec = user_db_module.getRecordByUserName( name )
	print("Try to get " .. name .. "'s record")
	if( rec ) then 
		print( "Found it: " )
		table.print_r( rec ) -- print_r() from extensions/table.lua
	else
		print( "Not found!" )
	end 
end

test_find( "Sue" )  -- This should produce a record
test_find( "Bill" ) -- There is no Bill

--
print( "\n *******************  ")
local function test_remove( name, pass )
	local success, reason = user_db_module.removeRecordByNamePass( name, pass )
	print( "Tried to remove user: " .. name .. " password: " .. pass )
	print( success, reason )
end

test_remove( "Bill", "funkyMonkey" ) -- No Bill
test_remove( "Sue", "funkyMonkey" ) -- Wrong password
test_remove( "Sue", "mypass456" ) -- Will delete Sue
test_remove( "Sue", "mypass456" ) -- No Sue (we just deleted her record
test_remove( "Bob", "mypass123" ) -- Bye, bye Bob... now no users in DB.

user_db_module.printUsers() 

Please check my model and see what I did wrong.
in main.lu ----Run the add user function first to add some user before running remove user function.
Model.zip (18.0 KB)

Fixed copy: https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2022/06/Model_fixed.zip

Steps taken to fix:

  1. Replaced your user_db_module.lua with the one from here: https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2022/06/userDB.zip

  2. Replaced this code (in remove.lua):

   -- Rule A1 - Length >= 4
   if( string.len(userid) < 4 ) then       
      labelReturnStatus1.text = "invalid password (too short)!" 

   -- Clear warning label and save new user record
   else
      labelReturnStatus1.text = ""
      labelReturnStatus2.text = userid .. "  successfully removed"
     
local success, reason = user_db_module.removeRecordByNamePass( userid, password )
if(  success ) then
     print( "User " .. userid .. " record successfully removed" )
else
     print( "User " .. userid .. " record not removed.  Reason: " .. reason  )
end

with this:

   -- Rule A1 - Length >= 4
   if( string.len(userid) < 4 ) then       
      labelReturnStatus1.text = "invalid password (too short)!" 
   else     
      local success, reason = user_db_module.removeRecordByNamePass( userid, password )
      if(  success ) then
         print( "User " .. userid .. " record successfully removed" )
      else
         print( "User " .. userid .. " record not removed.  Reason: " .. reason  )
      end
      labelReturnStatus1.text = userid
      labelReturnStatus2.text = reason

Okay it’s fixed the problem was the user_db_module. I just replace it by the new one and it works !
please check the corrected file to continue help me in my project.
Corrected model.zip (18.6 KB)

I posted a fix above.

Tip: I’d suggest taking great care to maintain clean code or your project will become hard to understand and work with.

I noticed a lot of unnecessary blank lines and incorrect indentation levels.

I also noticed this:

-- 1 Initialize the local copy of the DB 
local user_db_module = require "scripts.user_db_module"
user_db_module.init() 


-- 1. Run this a few times first and add some names...
--local Add user = require "scripts.example"

-- 2. ...then comment out above and run this....
-- Basic dump of names list to scrollview
 local scroll_example = require "scripts.scroll_example"


-- 1. Run this to remove some names...
local remove = require "scripts.remove"

which should have been more like this:

-- 1 Initialize the local copy of the DB 
local user_db_module = require "scripts.user_db_module"
user_db_module.init() 

-- 2. Run this a few times first and add some names...
require "scripts.example"

-- 3. ...then comment out above and run this....
-- Basic dump of names list to scrollview
-- require "scripts.scroll_example"

-- 4. Run this to remove some names...
--require "scripts.remove"