Remove special characters from array elements and mix it with another array - robotframework

I apologize if this is repeated, but I'm total noob with Robot framework, and I would need help. I have two arrays, results from database:
#{users}= query Select * from users
#{fieldNames}= query SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'robot_test' AND TABLE_NAME = 'users';
Results that I get from this are:
#{users}= (1, 'user1', 'pass1', 'admin'), (2, 'user2', 'pass2', 'user')
#{fieldNames} = [ ('id',) | ('username',) | ('password',) | ('role',) ]
I would like to filter #(fieldNames) to become
#{fieldNames} = [ 'id','username','password','role']
And then to mix it with #(users) to get
#{mixedArray}= (('id',1) , ('username','user1'), ('password','pass1'), ('role','admin')), (('id',2) , ('username','user2'), ('password','pass2'), ('role','user'))
Is there a way to do this? Thanks everyone for help.

Because database library returns query results as a list of tuples, you can just iterate through them. Only cleaning I did was to use Combine Lists to get rid of tuples inside fieldNames list.
*** Settings ***
# Library Dialogs
Library Collections
Library DatabaseLibrary
library pymysql
*** Variables ***
#{database} pymysql users root df478444 localhost 3306
*** Test Cases ***
Stackoverflow
Connect To Database #{database}
#{users}= query Select * from Users
#{fieldNames}= query SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'users' AND TABLE_NAME = 'Users';
#{fields list}= Combine Lists #{fieldNames}
#{mixedArray}= Create List
:FOR ${user} IN #{users}
\ ${user row}= parse user ${user} ${fields list}
\ Append To List ${mixedArray} ${user row}
Log ${mixedArray}
*** Keywords ***
Parse User
[Arguments] ${user} ${fields}
#{line}= Create List
${list length}= Get Length ${fields}
:FOR ${i} IN RANGE ${list length}
\ #{pair}= Create List
\ ${f}= Get From List ${fields} ${i}
\ ${u}= Get From List ${user} ${i}
\ Append To List ${pair} ${f}
\ Append To List ${pair} ${u}
\ Append To List ${line} ${pair}
Return From Keyword ${line}

Related

Robot Framework ellipsis concatenate adding commas

In Robot Framework when I try and use the ellipsis to put a long statement on multiple lines it is adding a comma at the break.
${Built_query} = Set Variable select oid, activityCode, activity_description from tblActivity
... where ACTIVITY_ENDDATE is null order by oid
And that's 4 spaces ellipsis and two spaces.
the result is:
'select oid, activityCode, activity_description from tblActivity', 'where ACTIVITY_ENDDATE is null order by oid'
Any help will be appreciated.
Sam.
When you use ..., each line represents one or more arguments to the keyword. In your case, Set Variable is seeing two separate arguments. When Set Variable gets more than one argument, it creates a list.
If you want to create a string that is spread out on different lines, you need to use Catenate. With Catenate you can define what is used to join each line. By default it uses a single space.
${Built_query}= Catenate
... select oid, activityCode, activity_description from tblActivity
... where ACTIVITY_ENDDATE is null order by oid
Here is a complete test, which passes when run:
*** Test Cases ***
Example
${Built_query}= Catenate
... select oid, activityCode, activity_description from tblActivity
... where ACTIVITY_ENDDATE is null order by oid
Should be equal
... ${Built_query}
... select oid, activityCode, activity_description from tblActivity where ACTIVITY_ENDDATE is null order by oid

Robot Framework - How to if statement if keyword fails

${Var_Name}= page should contain element ${ID}
run keyword if "some keyword" ${Var_Name} false
If the page doesn't contain the element the test fails, is it possible to ignore the fail and run "some keyword" as it returns false?
The keyword 'page should contain element' does not return anything, so ${Var_Name} will not contain a value apart from 'None' when the 'page should contain element' test succeeds.
You could use the keyword "Get Matching Xpath Count" from the selenium2Library and perform the required action in an if/else statement based on the value of the xpath count.
like so:
${value}= | Get Matching Xpath Count | [xpath]
Run Keyword If | ${value} > 0 | [keyword]
... | ELSE | [keyword]

Search entire SQLite database for ID

I'm using SQLiteStudio to view and test an sqlite database which means I don't have access to fts3 or fts4.
I have an id which I need to find from within the database and have no idea which of the 45 tables it belongs to. Is there a query I can run that will return the table name it belongs to?
There's a solution to do this in SQLiteStudio. Note, that this does a full scan across all tables, all columns in every table (until it finds the match - then it stops), so this can be very slow. Be warned.
Here's how you do it:
Run SQLiteStudio, open "Custom SQL functions" dialog (it's the one with a blue brick icon).
Add new function, for exampe "find" and set its implementation language to Tcl (in top right corner). Paste following code as an implementation.
set value [string map [list "'" "''"] $0]
foreach table [db eval {select name from sqlite_master where type = "table"}] {
set cols [list]
foreach infoRow [db getTableInfo $table] {
lappend cols "\[[dict get $infoRow name]\] = '$value'"
}
set res [db eval "SELECT rowid FROM \[$table\] WHERE [join $cols { OR }]"]
if {[llength $res] > 0} {
return "found in table $table in rows with following ROWID: [join $res ,\ ]"
}
}
return "not found"
Use it from SQL query like this:
select find('your-id');
The function will scan table after table to find your-id. Once it finds a table, it will print ROWIDs of all rows that matched your-id. It will return something like:
found in table Products in rows with following ROWID: 345, 4647, 32546
Then you can query Products table using those ROWIDs:
select * from Products where rowid in (345, 4647, 32546);
If your-id will not be found, then the result of find will be: not found.
Write this shell script into a file named dbSearchString.sh:
#!/bin/sh
searchFor="$1"
db="$2"
sqlite3 "$db" .tables | while read table; do
output=`sqlite3 -line "$db" "select * from $table" | grep "$searchFor"`
if [[ "$?" -eq 0 ]]; then
echo "Found in ${table}:"
echo "$output"
fi
done
Then use it like this:
$ dbSearchString.sh "text to search for" database.db

Unix field empty in the output query

when i make this code:
ENDROW=""
while read ENDROW;
do
temp=${ENDROW##*##;} field1=`printf '"%s"\n' "${temp%%##;*}"
#Here the insert >> ${sqlfile}
and look at the ${sqlfile} output the fieldare empty... Seems that the code to find the field between the separators finished when it finds the first separator and then doesn't go on. Why?
Given the input you indicate in the comments:
$ cat file
##
field1##
field2##
field3##
field4##
field5
This could work:
while read ENDROW
do
echo ${ENDROW%*##}
done < file
That is, your substitution must be made with % (strip ... from back) rather than ## (strip... from front).
Test
$ while read ENDROW; do echo ${ENDROW%*##}; done < file
field1
field2
field3
field4
field5
In your case
#ENDROW="" #is not necessary
while read ENDROW;
do
temp=${ENDROW%*##}
field1=$(printf '"%s"\n' "$temp")
#Here the insert >> ${sqlfile}
To read more about bash substitution:
- wooledge.org - How can I use parameter expansion? How can I get substrings? How can I get a file without its extension, or get just a file's extension?
- Shell Command Language - 2.6.2 Parameter Expansion

How to handle a missing feature of SQLite : disable triggers?

How to handle a missing feature of SQLite: disable triggers?
I don't have it stored the name of triggers for a specific table.
For example how can I drop all triggers?
What would you do?
So here it is 2015 and there still is no 'disable triggers' in SQLite. For a mobile Application this can be problematic--especially if it's a corporate App requiring offline functionality and local data.
An initial data load can be slowed to crawl by trigger execution even when you don't wrap each insert in an individual transaction.
I solved this issue using SQLite SQL fairly simply. I have a settings table that doesn't participate in the init load. It holds 'list' of key/value pairs. I have one key called 'fireTrigger' with a bit value of 0 or 1. Every trigger I have has an expression that selects value and if it equals 1 it fires the trigger, otherwise it doesn't.
This expression is in addition to any expressions evaluated on the data relating to the trigger. e.g.:
AND 1 = (SELECT val FROM MTSSettings WHERE key = 'fireTrigger')
In simple clean effect this allows me to disable/enable the trigger with a simple UPDATE to the settings table
I wrote a very simple extension function to set a boolean value to true or false.
And a function to retrieve this value (GetAllTriggersOn()).
With this function I can define all my triggers like:
CREATE TRIGGER tr_table1_update AFTER UPDATE ON TABLE1 WHEN GetAllTriggersOn()
BEGIN
-- ...
END
SQLite stores schema (meta) information in the built-in sqlite_master table.
To get a list of available triggers use the below query:
SELECT name FROM sqlite_master
WHERE type = 'trigger' -- AND tbl_name = 'a_table_name'
Set a flag in your database and use it in the triggers WHEN condition.
Say you want to create a trigger on the "clients" table after an insert. You have created a table "trigger_settings" with a TINYINT "triggers_on" field - this is your flag. Then you can set the field to 0 if you want to turn off the filters and to 1 when you want to turn them back on.
Then you create your filter with a WHEN condition that checks the "triggers_on" field.
For example:
CREATE TRIGGER IF NOT EXISTS log_client_data_after_insert
AFTER INSERT
ON [clients]
WHEN (SELECT triggers_on FROM trigger_settings)=1
BEGIN
your_statement
END;
Maybe you can make a stored procedures for droping and creating them. Is that good for you ?
Expanding on Nick Dandoulakis's answer, you could drop all relevant triggers and then reinstate them before the transaction's completion:
BEGIN;
SELECT name, sql FROM sqlite_master WHERE type = 'trigger' AND tbl_name = 'mytable';
-- store all results
-- for each name: DROP TRIGGER $name;
-- do normal work
-- for each sql: execute the SQL verbatim
COMMIT;
Expanding other answers this is how i'm doing it. Take into account that this is disabling all triggers for all tables in the database except some of then used by spatialite
SQLITE_FILE=/tmp/my.sqlite
# Define output sql files as variables
CREATE_TRIGGER_SQL=/tmp/create_triggers.sql
DROP_TRIGGER_SQL=/tmp/drop_triggers.sql
## Dump CREATE TRIGGER statements to a file ##
# To wrap statements in a transaction
echo -e "BEGIN;\n\n" > "${CREATE_TRIGGER_SQL}"
# `SELECT sql` does not output semicolons, so we must concatenate them
sqlite3 -bail "${SQLITE_FILE}" "SELECT sql || ';' FROM sqlite_master WHERE type = 'trigger' AND (name NOT LIKE 'gid_%' AND name NOT LIKE 'ggi_%' AND name NOT LIKE 'ggu_%' AND name NOT LIKE 'gii_%' AND name NOT LIKE 'giu_%' AND name NOT LIKE 'vwgcau_%' AND name NOT LIKE 'vtgcau_%' AND name NOT LIKE 'gcau_%' AND name NOT LIKE 'geometry_columns_%' AND name NOT LIKE 'gcfi_%' AND name NOT LIKE 'gctm_%' AND name NOT LIKE 'vtgcfi_%' AND name NOT LIKE 'vwgcfi_%' AND name NOT LIKE 'vtgcs_%' AND name NOT LIKE 'vwgc_%' AND name NOT LIKE 'vtgc_%' AND name NOT LIKE 'gcs_%');" >> "${CREATE_TRIGGER_SQL}"
echo -e "\n\nCOMMIT;" >> "${CREATE_TRIGGER_SQL}"
## Dump DROP TRIGGER statements to a file ##
echo -e "BEGIN;\n\n" > "${DROP_TRIGGER_SQL}"
sqlite3 -bail "${SQLITE_FILE}" "SELECT 'DROP TRIGGER ' || name || ';' FROM sqlite_master WHERE type = 'trigger' AND (name NOT LIKE 'gid_%' AND name NOT LIKE 'ggi_%' AND name NOT LIKE 'ggu_%' AND name NOT LIKE 'gii_%' AND name NOT LIKE 'giu_%' AND name NOT LIKE 'vwgcau_%' AND name NOT LIKE 'vtgcau_%' AND name NOT LIKE 'gcau_%' AND name NOT LIKE 'geometry_columns_%' AND name NOT LIKE 'gcfi_%' AND name NOT LIKE 'gctm_%' AND name NOT LIKE 'vtgcfi_%' AND name NOT LIKE 'vwgcfi_%' AND name NOT LIKE 'vtgcs_%' AND name NOT LIKE 'vwgc_%' AND name NOT LIKE 'vtgc_%' AND name NOT LIKE 'gcs_%');" >> "${DROP_TRIGGER_SQL}"
echo -e "\n\nCOMMIT;" >> "${DROP_TRIGGER_SQL}"
## Execute like ##
sqlite3 -bail /"${SQLITE_FILE}" < "${DROP_TRIGGER_SQL}"
# do things
sqlite3 -bail /"${SQLITE_FILE}" < "${CREATE_TRIGGER_SQL}"

Resources