Cypher - Conditional Create - database

How Normal Create Works in a Database
In most create circumstances, you don't want to create a new node if one of the unique or primary keys already exist in the database. I also don't want to update the node, as that would be an upsert. I want to do nothing if the key exists in the database. This will work just like a unique constraint.
Create with a Unique Key
If I want only the email field to be unique, I can do this:
MERGE (u:User { email: 'me#you.com' })
ON CREATE SET u.name='Jon Smith'
RETURN u
It won't create the user if there is already an email.
Create with Multiple Unique Keys ?
Let's say I don't want the user to be able to create a user where a username or email is already in the database. You would think this would work:
MERGE (u:User { email: 'me#you.com', username: 'bill' })
ON CREATE SET u.name='Jon Smith'
RETURN u
However, this will still create the node, as only the COMBINATION has to be unique. I want both values separately to be unique... or fail.
Conditional Create
What I want is a conditional create: IF X THEN Y where:
x = email OR username IS NOT IN User
y = CREATE User email="me#you.com", username="bill", role="admin", ...
How can this be done?
J

Please consider the following query:
GRAPH.QUERY g "cypher email='a' username='b'
OPTIONAL MATCH (n)
WHERE n.email = $email OR n.username = $username
WITH n is null as missing
WHERE missing = true
CREATE ({email:$email, username:$username})"
Given an empty graph:
GRAPH.QUERY g "cypher email='a' username='b' OPTIONAL MATCH (n) WHERE n.email = $email OR n.username = $username WITH n is null as missing WHERE missing = true CREATE (n {email:$email, username:$username})"
1) 1) "Nodes created: 1"
2) "Properties set: 2"
3) "Cached execution: 0"
4) "Query internal execution time: 1.469000 milliseconds"
GRAPH.QUERY g "cypher email='a' username='b' OPTIONAL MATCH (n) WHERE n.email = $email OR n.username = $username WITH n is null as missing WHERE missing = true CREATE (n {email:$email, username:$username})"
1) 1) "Cached execution: 1"
2) "Query internal execution time: 0.614000 milliseconds"
Running the exact same query twice, the first execution created the missing node the second one didn't modified the graph.

Related

Reading data from SQLite3 database and using them

To start off, I really don't know if this have been answered before.
I looked all over but still couldn't find an example..
And I'm new to SQLite3 and obviously I would run into these kind of problems.
Basically what I'm doing is creating a SQLite3 database save as : "Data.dll".
And I've created a table and inserted some data in there..
Now, basically what I want to do is like ask the user a question, and the user has to input a number AND a "Key".
When inputted I want to check if it's valid.
For example,
DATA #1 :
NUMBERID : 30138
KEY: KeyUser1
DATA #2 :
NUMBERID : 1144
KEY : key2
If those were both inputted (Like 30138, and KeyUser1. not like 30138 and key2) then they can keep going, otherwise, It would say that the NUMBER ID and "KEY" Do not match.
So how can I do that?
I'm new to SQLite3 and so I'm still a newbie...
Any help is appreciated.
My Code:
import sqlite3
dbase = sqlite3.connect("Data.dll")
print "DataBase Opened : Success."
dbase.execute(""" CREATE TABLE IF NOT EXISTS Keys(
NUMBERID INT PRIMARY KEY NOT NULL,
VAILD TEXT NOT NULL)""")
print "DataBase Table : Success"
def insert_record(NUMBERID,VAILD):
dbase.execute(""" INSERT INTO Keys (NUMBERID,VAILD)
VALUES(?,?)""", (NUMBERID,VAILD))
dbase.commit()
#insert_record(1144, 'key2') # If needed to insert soemthing...
print "DataBase Insert : Success."
def read_Data():
data = dbase.execute(""" SELECT NUMBERID,VAILD FROM Keys """)
for record in data:
NUMBER_ID = str(record[0])
VAILD_KEY = str (record [1])
print NUMBER_ID # Check
print VAILD_KEY # Check
read_Data()
NUMBER_ENTER = input ("Enter NUMBER ID : ")
VAILD_ENTER = raw_input ("Enter KEY : ")
if NUMBER_ENTER in NUMBER_ID:
print "1" # If its at least correct print this
...
else:
print "2" # wrong
...
if VAILD_ENTER in VAILD_KEY:
print "a" # if its at least correct , print this.
...
else:
print "z" # wrong
...
dbase.close()
print "DataBase Closed : Success."
you could try this:
def check(number, key):
data = dbase.execute("select 1 from keys where NUMBERID = ? AND VAILD = ?", (number, key)).fetchone()
return data
NUMBER_ENTER = input("Enter NUMBER ID : ")
VAILD_ENTER = raw_input("Enter KEY : ")
if check(NUMBER_ENTER, VAILD_ENTER):
print 1
else:
print 2
where you check if there is a row with the NUMBERID, VAILD

sqlite3 selecting values based on python variables

I am trying to select a value from my python SQL table based on a variable that the user inputs, through Tkinter. My database has a column named employee_username and has the employee's usernames and their password in 1 row. Username is entered by the user in a tkinter window
My code looks like this:
import sqlite3
import password_database
import tkinter
conn = sqlite3.connect('passwordDb.db')
c = conn.cursor()
username=entry_user.get()
password=entry_user.get()
database_username=c.execute(SELECT * FROM passwordDb WHERE
employee_username=username)
if database_username!=' ':
print('you entered a username which is not in the database')
else:
running=True
When I run this code I am not able to get any results. How do I manage to check if the value the user enters is in my database and how to I retrieve employee's password attached to the username.
Thanks in advance
Your code is not complete but I guess i understand you.
Before you query the database, you need to strip of white spaces from the username or the input
username = input("username")
db_username = username.strip() #this removes the white space
# you can then check to see if the username is none...
records = cur.fetchall(); # this would return all matching records, loop through
if not database_user is None:
...
else:
print("your username is bad")
I see few mistakes
First: query should be as string, and it should have ? and username should be tuple (username, ) as argument
c.execute("SELECT * FROM passwordDb WHERE employee_username=?", (username, ))
Second: you have to use fetchall() or fetchone()` to get list with results or first result.
rows = cur.fetchall()
row = cur.fetchone()
Third: execute() doesn't have to return value so there is no sense to comparer with string " ". fetchall()/fetchone()` returns row(s) with result(s) so you can check how many rows it returned.
rows = cur.fetchall()
if len(rows) != 1:
print("your username is bad or duplicate")
or
rows = cur.fetchall()
if cur.rowcount != 1:
print("your username is bad or duplicate")

SQLITE check if table exist in C [duplicate]

How do I, reliably, check in SQLite, whether a particular user table exists?
I am not asking for unreliable ways like checking if a "select *" on the table returned an error or not (is this even a good idea?).
The reason is like this:
In my program, I need to create and then populate some tables if they do not exist already.
If they do already exist, I need to update some tables.
Should I take some other path instead to signal that the tables in question have already been created - say for example, by creating/putting/setting a certain flag in my program initialization/settings file on disk or something?
Or does my approach make sense?
I missed that FAQ entry.
Anyway, for future reference, the complete query is:
SELECT name FROM sqlite_master WHERE type='table' AND name='{table_name}';
Where {table_name} is the name of the table to check.
Documentation section for reference: Database File Format. 2.6. Storage Of The SQL Database Schema
This will return a list of tables with the name specified; that is, the cursor will have a count of 0 (does not exist) or a count of 1 (does exist)
If you're using SQLite version 3.3+ you can easily create a table with:
create table if not exists TableName (col1 typ1, ..., colN typN)
In the same way, you can remove a table only if it exists by using:
drop table if exists TableName
A variation would be to use SELECT COUNT(*) instead of SELECT NAME, i.e.
SELECT count(*) FROM sqlite_master WHERE type='table' AND name='table_name';
This will return 0, if the table doesn't exist, 1 if it does. This is probably useful in your programming since a numerical result is quicker / easier to process. The following illustrates how you would do this in Android using SQLiteDatabase, Cursor, rawQuery with parameters.
boolean tableExists(SQLiteDatabase db, String tableName)
{
if (tableName == null || db == null || !db.isOpen())
{
return false;
}
Cursor cursor = db.rawQuery(
"SELECT COUNT(*) FROM sqlite_master WHERE type = ? AND name = ?",
new String[] {"table", tableName}
);
if (!cursor.moveToFirst())
{
cursor.close();
return false;
}
int count = cursor.getInt(0);
cursor.close();
return count > 0;
}
You could try:
SELECT name FROM sqlite_master WHERE name='table_name'
See (7) How do I list all tables/indices contained in an SQLite database in the SQLite FAQ:
SELECT name FROM sqlite_master
WHERE type='table'
ORDER BY name;
Use:
PRAGMA table_info(your_table_name)
If the resulting table is empty then your_table_name doesn't exist.
Documentation:
PRAGMA schema.table_info(table-name);
This pragma returns one row for each column in the named table. Columns in the result set include the column name, data type, whether or not the column can be NULL, and the default value for the column. The "pk" column in the result set is zero for columns that are not part of the primary key, and is the index of the column in the primary key for columns that are part of the primary key.
The table named in the table_info pragma can also be a view.
Example output:
cid|name|type|notnull|dflt_value|pk
0|id|INTEGER|0||1
1|json|JSON|0||0
2|name|TEXT|0||0
SQLite table names are case insensitive, but comparison is case sensitive by default. To make this work properly in all cases you need to add COLLATE NOCASE.
SELECT name FROM sqlite_master WHERE type='table' AND name='table_name' COLLATE NOCASE
If you are getting a "table already exists" error, make changes in the SQL string as below:
CREATE table IF NOT EXISTS table_name (para1,para2);
This way you can avoid the exceptions.
If you're using fmdb, I think you can just import FMDatabaseAdditions and use the bool function:
[yourfmdbDatabase tableExists:tableName].
The following code returns 1 if the table exists or 0 if the table does not exist.
SELECT CASE WHEN tbl_name = "name" THEN 1 ELSE 0 END FROM sqlite_master WHERE tbl_name = "name" AND type = "table"
Note that to check whether a table exists in the TEMP database, you must use sqlite_temp_master instead of sqlite_master:
SELECT name FROM sqlite_temp_master WHERE type='table' AND name='table_name';
Here's the function that I used:
Given an SQLDatabase Object = db
public boolean exists(String table) {
try {
db.query("SELECT * FROM " + table);
return true;
} catch (SQLException e) {
return false;
}
}
Use this code:
SELECT name FROM sqlite_master WHERE type='table' AND name='yourTableName';
If the returned array count is equal to 1 it means the table exists. Otherwise it does not exist.
class CPhoenixDatabase():
def __init__(self, dbname):
self.dbname = dbname
self.conn = sqlite3.connect(dbname)
def is_table(self, table_name):
""" This method seems to be working now"""
query = "SELECT name from sqlite_master WHERE type='table' AND name='{" + table_name + "}';"
cursor = self.conn.execute(query)
result = cursor.fetchone()
if result == None:
return False
else:
return True
Note: This is working now on my Mac with Python 3.7.1
You can write the following query to check the table existance.
SELECT name FROM sqlite_master WHERE name='table_name'
Here 'table_name' is your table name what you created. For example
CREATE TABLE IF NOT EXISTS country(country_id INTEGER PRIMARY KEY AUTOINCREMENT, country_code TEXT, country_name TEXT)"
and check
SELECT name FROM sqlite_master WHERE name='country'
Use
SELECT 1 FROM table LIMIT 1;
to prevent all records from being read.
Using a simple SELECT query is - in my opinion - quite reliable. Most of all it can check table existence in many different database types (SQLite / MySQL).
SELECT 1 FROM table;
It makes sense when you can use other reliable mechanism for determining if the query succeeded (for example, you query a database via QSqlQuery in Qt).
The most reliable way I have found in C# right now, using the latest sqlite-net-pcl nuget package (1.5.231) which is using SQLite 3, is as follows:
var result = database.GetTableInfo(tableName);
if ((result == null) || (result.Count == 0))
{
database.CreateTable<T>(CreateFlags.AllImplicit);
}
The function dbExistsTable() from R DBI package simplifies this problem for R programmers. See the example below:
library(DBI)
con <- dbConnect(RSQLite::SQLite(), ":memory:")
# let us check if table iris exists in the database
dbExistsTable(con, "iris")
### returns FALSE
# now let us create the table iris below,
dbCreateTable(con, "iris", iris)
# Again let us check if the table iris exists in the database,
dbExistsTable(con, "iris")
### returns TRUE
I thought I'd put my 2 cents to this discussion, even if it's rather old one..
This query returns scalar 1 if the table exists and 0 otherwise.
select
case when exists
(select 1 from sqlite_master WHERE type='table' and name = 'your_table')
then 1
else 0
end as TableExists
My preferred approach:
SELECT "name" FROM pragma_table_info("table_name") LIMIT 1;
If you get a row result, the table exists. This is better (for me) then checking with sqlite_master, as it will also check attached and temp databases.
This is my code for SQLite Cordova:
get_columnNames('LastUpdate', function (data) {
if (data.length > 0) { // In data you also have columnNames
console.log("Table full");
}
else {
console.log("Table empty");
}
});
And the other one:
function get_columnNames(tableName, callback) {
myDb.transaction(function (transaction) {
var query_exec = "SELECT name, sql FROM sqlite_master WHERE type='table' AND name ='" + tableName + "'";
transaction.executeSql(query_exec, [], function (tx, results) {
var columnNames = [];
var len = results.rows.length;
if (len>0){
var columnParts = results.rows.item(0).sql.replace(/^[^\(]+\(([^\)]+)\)/g, '$1').split(','); ///// RegEx
for (i in columnParts) {
if (typeof columnParts[i] === 'string')
columnNames.push(columnParts[i].split(" ")[0]);
};
callback(columnNames);
}
else callback(columnNames);
});
});
}
Table exists or not in database in swift
func tableExists(_ tableName:String) -> Bool {
sqlStatement = "SELECT name FROM sqlite_master WHERE type='table' AND name='\(tableName)'"
if sqlite3_prepare_v2(database, sqlStatement,-1, &compiledStatement, nil) == SQLITE_OK {
if sqlite3_step(compiledStatement) == SQLITE_ROW {
return true
}
else {
return false
}
}
else {
return false
}
sqlite3_finalize(compiledStatement)
}
c++ function checks db and all attached databases for existance of table and (optionally) column.
bool exists(sqlite3 *db, string tbl, string col="1")
{
sqlite3_stmt *stmt;
bool b = sqlite3_prepare_v2(db, ("select "+col+" from "+tbl).c_str(),
-1, &stmt, 0) == SQLITE_OK;
sqlite3_finalize(stmt);
return b;
}
Edit: Recently discovered the sqlite3_table_column_metadata function. Hence
bool exists(sqlite3* db,const char *tbl,const char *col=0)
{return sqlite3_table_column_metadata(db,0,tbl,col,0,0,0,0,0)==SQLITE_OK;}
You can also use db metadata to check if the table exists.
DatabaseMetaData md = connection.getMetaData();
ResultSet resultSet = md.getTables(null, null, tableName, null);
if (resultSet.next()) {
return true;
}
If you are running it with the python file and using sqlite3 obviously. Open command prompt or bash whatever you are using use
python3 file_name.py first in which your sql code is written.
Then Run sqlite3 file_name.db.
.table this command will give tables if they exist.
I wanted to add on Diego Vélez answer regarding the PRAGMA statement.
From https://sqlite.org/pragma.html we get some useful functions that can can return information about our database.
Here I quote the following:
For example, information about the columns in an index can be read using the index_info pragma as follows:
PRAGMA index_info('idx52');
Or, the same content can be read using:
SELECT * FROM pragma_index_info('idx52');
The advantage of the table-valued function format is that the query can return just a subset of the PRAGMA columns, can include a WHERE clause, can use aggregate functions, and the table-valued function can be just one of several data sources in a join...
Diego's answer gave PRAGMA table_info(table_name) like an option, but this won't be of much use in your other queries.
So, to answer the OPs question and to improve Diegos answer, you can do
SELECT * FROM pragma_table_info('table_name');
or even better,
SELECT name FROM pragma_table_list('table_name');
if you want to mimic PoorLuzers top-voted answer.
If you deal with Big Table, I made a simple hack with Python and Sqlite and you can make the similar idea with any other language
Step 1: Don't use (if not exists) in your create table command
you may know that this if you run this command that will have an exception if you already created the table before, and want to create it again, but this will lead us to the 2nd step.
Step 2: use try and except (or try and catch for other languages) to handle the last exception
here if you didn't create the table before, the try case will continue, but if you already did, you can put do your process at except case and you will know that you already created the table.
Here is the code:
def create_table():
con = sqlite3.connect("lists.db")
cur = con.cursor()
try:
cur.execute('''CREATE TABLE UNSELECTED(
ID INTEGER PRIMARY KEY)''')
print('the table is created Now')
except sqlite3.OperationalError:
print('you already created the table before')
con.commit()
cur.close()
You can use a simple way, i use this method in C# and Xamarin,
public class LoginService : ILoginService
{
private SQLiteConnection dbconn;
}
in login service class, i have many methods for acces to the data in sqlite, i stored the data into a table, and the login page
it only shows when the user is not logged in.
for this purpose I only need to know if the table exists, in this case if it exists it is because it has data
public int ExisteSesion()
{
var rs = dbconn.GetTableInfo("Sesion");
return rs.Count;
}
if the table does not exist, it only returns a 0, if the table exists it is because it has data and it returns the total number of rows it has.
In the model I have specified the name that the table must receive to ensure its correct operation.
[Table("Sesion")]
public class Sesion
{
[PrimaryKey]
public int Id { get; set; }
public string Token { get; set; }
public string Usuario { get; set; }
}
Look into the "try - throw - catch" construct in C++. Most other programming languages have a similar construct for handling errors.

Trouble adding elements to a table (array in Lua)

I am attempting to create a table to serve as a small database for users:
users = {}
function create_new_user()
print("Enter a unique user name (up to 12 letters): ")
local name = io.read()
if #name > 12 then
print ("That name is too long.")
return create_new_user()
elseif users[name] then
print ("That name is already in use.")
return create_new_user()
else
table.insert(users, 1, name)
print("Your new user name is: ", users[name])
end
end
I understood from the manual that the line
table.insert(users, 1, name)
would insert the string value of name as an element of the users array. This is not the case-- whenever I run the script I get the following output:
Your new user name is: nil
You insert the element into the table, but you are trying to retrieve the value indexed by the value of name, which is not what you stored (you are using users[name] instead of users[1]). You can probably do something like this:
table.insert(users, name)
print("Your new user name is: ", name)
Note that table.insert(users, 1, name) may not do what you expect as this will prepend elements to the table. If you insert "abc" and "def" this way, then the users table will include elements {"def", "abc"} (in this particular order). To retrieve the last inserted element you can use users[1].
If you want to store values in a different order, you need to use table.insert(users, name), which will append elements to the table. To retrieve the last element you can use users[#users].
If you always want to store the added element in the first position in the table, then you can simply use users[1] = name.
Here you index the user table with a string (the name):
elseif users[name] then
You do the same here:
print("Your new user name is: ", users[name])
But you store the name with a numerical index:
table.insert(users, 1, name)
What you want instead of that line is:
users[name] = name
Or this (which would require changing the line that follows):
users[name] = true
The idea is you're only really using the keys, to create a lookup table.

Add value into database plus 1

In my database I have:
Row ID - Driver ID - Log ID.
Row ID is unique and auto-increments. What I want is for the Log ID to be unique for each row that has that Driver ID.
For example say a row is inserted with Driver ID 1 I want that row to have a Log ID of 1 but the next time a row is inserted with Driver ID 1 I want it to have a Log ID of 2.
How can I achieve this?
By way for database i am using PHPMyAdmin.
----------------Edit----------------------
This is what i have in my PHP now, but it says:
On the webpage: Incorrect integer value: '' for column 'FinesCost' at row 1
And i dump the variables and get this: string(2) "16" string(2) "16" string(2) "16" so i dont understand why it is saying incorrect integer value and why it is saying they are undefines because they are very clearly defined.
In the PHP error log: [19-Jul-2013 10:44:18 Europe/Minsk] PHP Notice: Undefined variable: FinesCostP‌ost2 in C:\inetpub\wwwroot\hosting\Dan\JWT\drivers-log-send.php on line 336
[19-Jul-2013 10:44:18 Europe/Minsk] PHP Notice: Undefined variable: TravelExpensesPo‌​st2 in C:\inetpub\wwwroot\hosting\Dan\JWT\drivers-log-send.php on line 336
///PHP TO INSERT DRIVER'S BANK DETAILS INTO BANK DATABASE
session_start();
$host=""; // Host name
$username=""; // Mysql username
$password=""; // Mysql password
$db_name=""; // Database name
$tbl_name="jwtdriversbank"; // Table name
$un = "";
$usrname = "";
$usrpass = "";
$userID = "";
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
if(isset ($_SESSION['usrName']))
{
$usrname = $_SESSION['usrName'];
}
else
{
echo "4";
}
//var_dump ($usrname);
if(isset ($_SESSION['usrPass']))
{
$usrpass = $_SESSION['usrPass'];
}
else
{
echo "5";
}
$sql="SELECT * FROM jwtdrivers WHERE username='$usrname' and password='$usrpass'";
$result=mysql_query($sql);
$rows=mysql_fetch_array($result);
$userID = $rows['id'];
//var_dump ($userID);
if($userID == "")
{
echo "3";
}
else
{
$TotalProfitPost = $TotalProfit;
$LateFeePost = $LateFee;
$FinesCostPost2 = $FinesCost;
$TravelExpensesPost2 = $TravelExpenses;
$FuelCostPost = $FuelCost;
$CargoDamagePost = $CargoDamage;
$TruckDamagePost = $TruckDamage;
var_dump ($TotalProfitPost);
var_dump($FinesCostPost2);
var_dump($TravelExpensesPost2);
$sql="INSERT INTO jwtdriversbank2 (DriverID, LogID, TotalProfit, LateFee, FinesCost, TravelExpenses, FuelCost, CargoDamage, TruckDamage) VALUES ('$userID', COALESCE((Select MAX(LogID) from jwtdriversbank2 tab2 where tab2.DriverID = '$userID'),0)+1,'$TotalProfitPost','$LateFeePost', '$FinesCostP‌ost2' , '$TravelExpensesPo‌​st2' ,'$FuelCostPost','$CargoDamagePost','$TruckDamagePost')";
$result = mysql_query($sql);
if($result)
{
}
else
{
die(mysql_error());
}
}
Add a primary key for the two columns.
It should do the trick.
Look at this link for help
ALTER TABLE table_name
ADD CONSTRAINT pk_DriverID PRIMARY KEY (DriverID,LogID)
Do not forget to drop the first primary key because you will not need it no more.
EDIT : COMPLETE WITH THE OTHER ANSWER
Here is the code to insert your data.
Insert into <table_name>
values p_RowID, p_DriverID, COALESCE((Select MAX(Log_id) from <table_name> tab2 where tab2.Driver_id = p_DriverID),0)+1;
That should close the question.
You did not defined variable because PHP can't read them.
I opened your program inside VIM editor and I found "<200c>" char inside $FineCostPost2 in the SQL query. You have to change it to make it work.
A quick solution would be to use a subquery to find the maximum log (last log id) then increment it, something like this
Insert into <table_name>
values p_RowID, p_DriverID, COALESCE((Select MAX(Log_id) from <table_name> tab2 where tab2.Driver_id = p_DriverID),0)+1;
Here p_RowID and p_DriverID are the values you pass to insert into your table. The Coalesce function would check the given value and if it is NULL then it would replace it with the second parameter, in this case 0

Resources