Community discussions

MikroTik App
 
ros44
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 74
Joined: Sun Feb 25, 2018 2:05 am
Location: Sofia, Bulgaria

Best way to store data - matrix (2D array) or something else

Mon Feb 08, 2021 11:50 pm

At the moment I use two startup scripts to define two key arrays with the following structure
username -> IP address and
username -> email address

Now my need expands and I want to create array/table/structure like this:
username -> ip addres, email addres, status, last status, something else, something else .

I've been reading around and I need some directions:

1. Is using 2D array the best way of storing/manipulating data in Microtik at the moment? Should/Can I use files or something else?

2. If using arrays is the case, in order for me to access the status of a specific username is there a way (I couldn't find it) to create a key array of arrays so that I can use the username as a key and then access the ip address, email, status, etc... with their column numbers? What is the most elegant way, cause using foreach and then searching feels too primitive?

Any other recommendations and best practices will be highly appreciated!
 
sin3vil
newbie
Posts: 34
Joined: Sat May 26, 2018 10:05 pm

Re: Best way to store data - matrix (2D array) or something else

Tue Feb 09, 2021 6:21 pm

Hi ros44,

Not sure what mileage you're gonna get out of dictionaries. I've been having some issues here.

A workaround is quite simple, assuming you always have all fields.
You can store each type of data in it's own array, in the same order as the usernames array.

i.e.
global func do={
local usernames ("bob","bill","mike")
local ips (192.168.1.1,192.168.1.2,192.168.1.3)
local emails ("bob@domain.com","bill@domain.com","mike@domain.com")
local otherstuff ("lion","tiger","giraffe")


if ($1="print") do={
foreach index,user in=$usernames do={
local ip [:pick $ips $index]
local email [:pick $emails $index]
local somethingelse [:pick $otherstuff $index]

put ("$user,$ip,$email,$somethingelse")
}
}


if ($1="getEmail") do={
local index [:find $usernames $2]
put [:pick $emails $index]
}

if ($1="getStuff") do={
local index [:find $usernames $2]
put [:pick $otherstuff $index]
}

}
which then you can use as such
[kntouskos@sini2] > $func print
bob,192.168.1.1,bob@domain.com,lion
bill,192.168.1.2,bill@domain.com,tiger
mike,192.168.1.3,mike@domain.com,giraffe
[kntouskos@sini2] > $func getEmail bill
bill@domain.com
[kntouskos@sini2] > $func getStuff mike
giraffe
That said, you're only temporary storing the data. It will be lost on reboot, so you need a way to load it each time.
Reading/writing to file is limited to 4096 bytes. There are some workarounds though.
If your data is static it's better to just add them in the script.
 
ros44
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 74
Joined: Sun Feb 25, 2018 2:05 am
Location: Sofia, Bulgaria

Re: Best way to store data - matrix (2D array) or something else

Tue Feb 09, 2021 6:59 pm

I may get elegance and clarity... if it works (referring to the issues you had).

Some of the data won't be static, but I don't care if it will be lost between reboots of the router. I will use what you suggest considering the fact that you tested it.

Thank you for your time replying to my question.
 
ros44
Frequent Visitor
Frequent Visitor
Topic Author
Posts: 74
Joined: Sun Feb 25, 2018 2:05 am
Location: Sofia, Bulgaria

Re: Best way to store data - matrix (2D array) or something else

Wed Feb 10, 2021 2:33 am

I found this forum post and did some tests. The result is the code below that seems pretty neat, tidy and readable, and works as I expected.

:global UserDatabase [:toarray ""];

# The key for the array is the username of the user.
# The structure of every user record is as follows:
# password | email | tel | last IP | something | something else |
:set ($UserDatabase->"username1") {"supersecret";"username1@example.com";"+123456789";"0.0.0.0";0;0};
:set ($UserDatabase->"username2") {"megasecret";"username2@example.com";"+987654321";"0.0.0.0";0;0};

# Printing specific property (column) of the data for specific user:
:put ($UserDatabase->"username1"->0);

Can someone elaborate if this approach has some issues or disadvantages?
What is the name of this data type I've created? Is it called key array of arrays?
 
PackElend
Member Candidate
Member Candidate
Posts: 269
Joined: Tue Sep 29, 2020 6:05 pm

Re: Best way to store data - matrix (2D array) or something else

Sun May 08, 2022 10:43 am

:global UserDatabase [:toarray ""];

# The key for the array is the username of the user.
# The structure of every user record is as follows:
# password | email | tel | last IP | something | something else |
:set ($UserDatabase->"username1") {"supersecret";"username1@example.com";"+123456789";"0.0.0.0";0;0};
:set ($UserDatabase->"username2") {"megasecret";"username2@example.com";"+987654321";"0.0.0.0";0;0};

# Printing specific property (column) of the data for specific user:
:put ($UserDatabase->"username1"->0);
is great a piece of code.

Any idea how to make
 :put [ :find $UserDatabase "username1"  -1 ]
wo to work?
I get only an empty result.
 
msatter
Forum Guru
Forum Guru
Posts: 2897
Joined: Tue Feb 18, 2014 12:56 am
Location: Netherlands / Nīderlande

Re: Best way to store data - matrix (2D array) or something else

Sun May 08, 2022 11:13 am

Who is online

Users browsing this forum: marcelofares and 31 guests