Bash script to send notification when a new data is added - database

I need to work on a bash script to monitor the user table and sends a notification email to the sales team containing the newly created username.
I am new to scripting and have a little idea on how to do that.
appreciate any help or instructions.

You tagged the question as DB2, in that RDBS you can create a trigger that send a message by email. You do not need bash in this case.
Let's suppose you have a table called users, and each time a new row is inserted, an email message will be sent.
CREATE or replace trigger t1
after insert on users
REFERENCING NEW AS N
FOR EACH ROW
BEGIN
DECLARE v_sender VARCHAR(30);
DECLARE v_recipients VARCHAR(60);
DECLARE v_subj VARCHAR(20);
DECLARE v_msg VARCHAR(200);
SET v_sender = 'kkent#mycorp.com';
SET v_recipients = 'bwayne#mycorp.com,pparker#mycorp.com';
SET v_subj = 'New user';
SET v_msg = 'There is a new user: ' || n.username;
CALL UTL_MAIL.SEND(v_sender, v_recipients, NULL, NULL, v_subj, v_msg);
END#
You have to configure DB2 with your SMTP server and other parameters: http://pic.dhe.ibm.com/infocenter/db2luw/v10r5/topic/com.ibm.db2.luw.apdv.sqlpl.doc/doc/r0055176.html

May be you can use the inotify tool to detect the file modification and use the mail tool to send the mail in you script, as for how to use the command, please refers to the specific documentation.

To send an email you could use gmail + mutt. Just follow this tutorial to see how to configure mutt.
Once mutt is configured, you can send email from a script using a command like this one:
echo "$BODY" | mutt -s "$SUBJECT" $EMAIL_ADDRESS
An example would be:
echo "User Bob has been added." | mutt -s "New User" example#example.com
You could also consider using prowl to send push notifications to an IOS device. Prowl has a perl script that can be executed from your bash script. This would provide near instant notification. Prowl can also prioritize notifications.

Related

Modifying values in master..sysprocesses [Sybase]

Is there a way to modify the column program_name in table master..sysprocesses?
I have found two methods, but both set the name during the creation of the connection:
Using parameter appname when executing an isql command
Adding parameter APP= in a connection string when opening an ODBC connection.
I am looking for a way to modify it AFTER it has been created.
I tried the following example:
sp_configure "allow updates",1
go
UPDATE master..sysprocesses
SET program_name = 'test'
where hostname = 'server'
and hostprocess = '23240'
go
sp_configure "allow updates",0
go
But failed:
Could not execute statement.
Table 'sysprocesses' can't be modified.
Sybase error code=270
Severity Level=16, State=1, Transaction State=0
Line 4
You can continue executing or stop.
Changes to column sysprocesses.program_name are not allowed after its been created. But there are three columns in sysprocesses which can be changed after creation of the connection
sysprocesses.clientname
sysprocesses.clientapplname
sysprocesses.clienthostname
Exerpt from the Sybase Infocenter website:
Changing user session information
The set command includes options
that allow you to assign each client an individual name, host name,
and application name. This is useful for differentiating among clients
in a system where many clients connect to Adaptive Server using the
same name, host name, or application name.
The partial syntax for the set command is:
set [clientname client_name | clienthostname host_name | clientapplname application_name]
where:
client_name – is the name you are assigning the client.
host_name – is the name of the host from which the client is
connecting.
application_name – is the application that is connecting to Adaptive
Server.
These parameters are stored in the clientname, clienthostname, and
clientapplname columns of the sysprocesses table.
For example, if a user logs in to Adaptive Server as "client1", you
can assign them an individual client name, host name, and application
name using commands similar to:
set clientname 'alison'
set clienthostname 'money1'
set clientapplname 'webserver2'
.
.
.
Use the client’s system process ID to view their connection
information. For example, if the user “alison” described above
connects with a spid of 13, issue the following command to view all
the connection information for this user:
select * from sysprocesses where spid = 13
To view the connection information for the current client connection (for example, if the user “alison” wanted to view her own connection information), enter:
select * from sysprocesses where spid = ##spid

Sqlite in C programming

I am trying to implement a server-client communication. I am executing a sql statement (SQLITE3)
"UPDATE users SET status=1 WHERE username='%s' AND password='%s';",user,pass);
using qlite3_prepare_v2
I know how to write to client, but I don't know how to CHECK if the 'status' has been set to 1 where username is user and password is pass AND how to send a reply to client: "Yes, the 'status' has been set to 1, you are now logged in"
int sqlite3_changes(sqlite3*); returns the number of rows modified, inserted or deleted by the most recently completed INSERT, UPDATE or DELETE statement.
After your query, check if one row was modified.
Source: https://www.sqlite.org/c3ref/changes.html

obtain the real identity of the connected user

dxStatusbar1.Panels1.Text :=
DataModule2.UniConnectDialog1.Connection.Username;
...gives me the username that has connected to sql server.
However the connected user has a different name in the actual database.
Example:
His login name for the sql server is 'John' and is user mapped to 'Northwind' database.
However in 'Northwind' database he is called 'John Smith'.
And this is the name (John Smith) I am trying to have displayed in dxStatusbar1.Panels1.Text
after he connects.
How can I get that ?
edit :
Tried Victoria suggestion :
UserName := DataModule2.UniConnection1.ExecSQL('SELECT :Result = CURRENT_USER', ['Result']);
dxStatusbar1.Panels[1].Text := UserName;
but get :
I couldn't find any UniDAC API way to get currently connected user name (not even for SDAC), so I would just issue a SQL command querying CURRENT_USER and grab the name from the result:
SELECT CURRENT_USER;
Or in the Unified SQL way with the USER function:
SELECT {fn USER};
Since you've mentioned stored procedure in your comment, it sounds to me like you probably want to get this information directly from a connection object without using query object. If that is so, you don't even need to have a stored procedure but execute directly command like this:
var
UserName: string;
begin
UserName := UniConnection1.ExecSQL('SELECT :Result = CURRENT_USER', ['Result']);
...
end;
Or in unified way:
var
UserName: string;
begin
UserName := UniConnection1.ExecSQL('SELECT :Result = {fn USER}', ['Result']);
...
end;
One of these might do the job for you. Haven't tested.
SELECT ORIGINAL_LOGIN()
SELECT SYSTEM_USER
SELECT SUSER_SNAME()
Hope it helps.
ORIGINAL_LOGIN: Returns the name of the login that connected to the instance of SQL Server. You can use this function to return the identity of the original login in sessions in which there are many explicit or implicit context switches.
SYSTEM_USER: Allows a system-supplied value for the current login to be inserted into a table when no default value is specified.
SUSER_SNAME: Returns the login name associated with a security identification number (SID).

What is the difference between user postgres and a superuser?

I created a new superuser just so that this user can run COPY command.
Note that a non-superuser cannot run a copy command.
I need this user due to a backup application, and that application requires to run COPY command
But all the restrictions that I specified does not take effect (see below).
What is the difference between user postgres and a superuser?
And is there a better way to achieve what I want? I looked into a function with security definer as postgres ... that seems a lot of work for multiple tables.
DROP ROLE IF EXISTS mynewuser;
CREATE ROLE mynewuser PASSWORD 'somepassword' SUPERUSER NOCREATEDB NOCREATEROLE NOINHERIT LOGIN;
-- ISSUE: the user can still CREATEDB, CREATEROLE
REVOKE UPDATE,DELETE,TRUNCATE ON ALL TABLES IN SCHEMA public, schema1, schema2, schema3 FROM mynewuser;
-- ISSUE: the user can still UPDATE, DELETE, TRUNCATE
REVOKE CREATE ON DATABASE ip2_sync_master FROM mynewuser;
-- ISSUE: the user can still create table;
You are describing a situation where a user can write files to the server where the database runs but is not a superuser. While not impossible, it's definitely abnormal. I would be very selective about who I allow to access my DB server.
That said, if this is the situation, I'd create a function to load the table (using copy), owned by the postgres user and grant the user rights to execute the function. You can pass the filename as a parameter.
If you want to get fancy, you can create a table of users and tables to define what users can upload to what tables and have the table name as a parameter also.
It's pretty outside of the norm, but it's an idea.
Here's a basic example:
CREATE OR REPLACE FUNCTION load_table(TABLENAME text, FILENAME text)
RETURNS character varying AS
$BODY$
DECLARE
can_upload integer;
BEGIN
select count (*)
into can_upload
from upload_permissions p
where p.user_name = current_user and p.table_name = TABLENAME;
if can_upload = 0 then
return 'Permission denied';
end if;
execute 'copy ' || TABLENAME ||
' from ''' || FILENAME || '''' ||
' csv';
return '';
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
COPY with option other than writing to STDOUT and reading from STDIN is only allowed for database superusers role since it allows reading or writing any file that the server has privileges to access.
\copy is a psql client command which serves the same functionality as COPY but is not server-sided, so only local files can be processed - meaning it invokes COPY but ... FROM STDIN / ... TO STDOUT, so that files on a server are not "touched".
You can not revoke specific rights from a superuser. I'm quoting docs on this one:
Docs: Access DB
Being a superuser means that you are not subject to access controls.
Docs: CREATE ROLE
"superuser", who can override all access restrictions within the database. Superuser status is dangerous and should be used only when really needed.

How to use prepared statements in lua-dbi?

I want to use prepared statements in my lua scripts. As mentioned in my previous post, people recommend using lua-dbi. Unfortunately there is little documentation available. I just need a basic script that connects to the database with credentials, and use prepared statements (prefered with a bind function to names in the query). Anyone experienced with this?
You can find it on the project's wiki pages:
Establishing connection: https://code.google.com/p/luadbi/wiki/DBDDriverConnection
require('DBI')
-- Create a connection
local dbh = assert(DBI.Connect('Driver', db, username, password, host, port))
-- set the autocommit flag
-- this is turned off by default
dbh:autocommit(true)
-- check status of the connection
local alive = dbh:ping()
-- prepare a connection
local sth = assert(dbh:prepare(sql_string))
-- commit the transaction
dbh:commit()
-- finish up
local ok = dbh:close()
where, you'd update the part dbh:prepare as per your needs.

Resources