MariaDB Node.js-Connector insert a value and use the default value - express

I have a MariaDB database in conjuction with an Express.js backend and therefore use the MariaDB provided Node.js Connector. I Initialized a Database with a Table that looks like this:
CREATE TABLE IF NOT EXISTS `Threads` (
`id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`title` TINYTEXT NOT NULL,
`post` TEXT NOT NULL,
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
`updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (`id`)
);
Using the Node.js-Connector in my Backend, I want to insert some data to this table and use the default values for "created_at" and "updated_at".
I was thinking of something like this:
const insertThreadQuery = 'INSERT INTO Threads VALUES (?, ?, ?, ?, ?)';
con = await pool.getConnection();
const result = await con.query(insertThreadQuery, [null, "title", "post", null, null]);
Which obivously throws an error that tells me, that I cannot insert null for these Values ((conn=4, no: 1048, SQLState: 23000) Column 'updated_at' cannot be null sql: INSERT INTO Threads VALUES (?, ?, ?, ?, ?) - parameters:[null,'title','post',null,null])
My question is: How can I insert an entry like I was showing before, but instead of inserting "null" insert something else so my columns created_at and updated_at use the default value?

If you want to use DEFAULT values, then pass DEFAULT instead of NULL.
const insertThreadQuery = 'INSERT INTO Threads VALUES (NULL, ?, ?, DEFAULT, DEFAULT)';
con = await pool.getConnection();
const result = await con.query(insertThreadQuery, ["title", "post"]);

Related

PhoneGap sql checking for duplicates

I want to input a query to check the database for duplicate when inserting data into the database so it would prevent the activity Name from being entered more than once in a database
function insertQueryDB(tx) {
var myDB = window.openDatabase("test", "1.0", "Test DB", 1000000);
tx.executeSql('CREATE TABLE IF NOT EXISTS dataEntryTb (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, activityName TEXT NOT NULL, location TEXT NOT NULL, time NOT NULL, date NOT NULL, reporter NOT NULL)');
var an = document.forms["myForm"]["activityName"].value;
var l = document.forms["myForm"]["location"].value;
var t = document.forms["myForm"]["time"].value;
var d = document.forms["myForm"]["date"].value;
var r = document.forms["myForm"]["reporter"].value;
var query = 'INSERT INTO dataEntryTb ( activityName, location, time, date, reporter) VALUES ( "'+an+'", "'+l+'", "'+t+'", "'+d+'", "'+r+'")';
navigator.notification.alert("Retrieved the following: Activity Name="+an+" and Location="+l);
tx.executeSql(query,[]);
}``
Create the table with name being unique:
CREATE TABLE IF NOT EXISTS dataEntryTb (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
activityName TEXT NOT NULL UNIQUE,
location TEXT NOT NULL,
time NOT NULL, date NOT NULL,
reporter NOT NULL
);
Then the database will return an error if the name is already in the table.

Change Spring Data Rest default message for DataIntegrityViolationException

I have a basic JPA Entity that I would like to expose via Spring-Data-Rest
#Entity
#Table(name='test')
class Test{
#Id
Long id
#Column(name='other_id', unique = true)
String otherId
#Column(name='other_crm_id')
String otherCrmId
#Column(name='created_date')
Date createdDate
#Column(name='created_by')
String createdBy
}
I would like to change the exception message that is thrown when the Unique constraint on 'otherId' fires. Currently the default ExceptionHandler for Spring Data Rest displays the following
{
-cause: {
-cause: {
cause: null
message: "Unique index or primary key violation:
\"UK_PJCWVB8DO3C89YTD1PNF85HQR_INDEX_2 ON PUBLIC.TEST(OTHER_ID) VALUES
( /* key:1 */ 2, NULL, NULL, 'ABC123424', '123')\"; SQL statement:\
insert into test (id, created_by, created_date, other_crm_id,
other_id) values (null, ?, ?, ?, ?) [23505-175]"
}
message: "could not execute statement"
}
message: "could not execute statement; SQL [n/a]; constraint
[\"UK_PJCWVB8DO3C89YTD1PNF85HQR_INDEX_2 ON PUBLIC.TEST(OTHER_ID) VALUES ( /* key:1
*/ 2, NULL, NULL, 'ABC123424', '123')\"; SQL statement:\ insert into test (id,
created_by, created_date, other_crm_id, other_id) values (null, ?, ?, ?, ?)
[23505-175]]; nested exception is
org.hibernate.exception.ConstraintViolationException: could not execute statement"
}
Not a big fan of the sql and table information being returned in the Response, so I've been attempting to change the message. I created a ExceptionHandlingController annotated with #ControlAdvice, but the ExceptionHandlers in AbstractRepositoryRestController.java take precedence.
My question is: What is the best way to change the error response for the DataIntegrityViolationException in Spring-Data-Rests default RepositoryEntityController?

Yii's updateByPk keeps returning 0

I'm trying to update my user table, which my code does. but for some reason it keeps executing the else statement.
in the documentation it states that updateByPk should return the number of rows being updated. Which should be 1. what am i missing here? and how do i check if the table has been updated successfully?
if (User::model()->updateByPk($model->id, array("last_login"=> Shared::timeNow())))
{
Yii::app()->user->login($identity, $duration);
echo json_encode(array('error' => false, 'success' => url(app()->users->getHomeUrl())));
Yii::app()->end();
}
else {
echo json_encode(array('error' => 'Could not update user info', 'code' => 'auth'));
Yii::app()->end();
}
my table schema is this
CREATE TABLE IF NOT EXISTS `user` (
`id` int(10) unsigned NOT NULL,
`username` varchar(100) DEFAULT NULL,
`email` varchar(255) NOT NULL,
`first_name` varchar(45) NOT NULL,
`last_name` varchar(45) NOT NULL,
`gender` char(1) DEFAULT NULL,
`birthday` date DEFAULT '0000-00-00',
`address` varchar(255) DEFAULT NULL,
`city` varchar(45) DEFAULT NULL,
`state` varchar(45) DEFAULT NULL,
`website` text,
`postal_code` varchar(45) DEFAULT NULL,
`phone` varchar(45) DEFAULT NULL,
`password` varchar(63) DEFAULT NULL,
`activate` varchar(63) NOT NULL DEFAULT '1',
`create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`last_login` datetime DEFAULT NULL,
`password_reset` int(11) unsigned DEFAULT NULL,
`admin` tinyint(1) unsigned NOT NULL DEFAULT '0',
`email_verified` tinyint(1) unsigned DEFAULT NULL,
`login_disabled` tinyint(1) unsigned NOT NULL DEFAULT '0',
`oauth_id` bigint(20) DEFAULT NULL,
`oauth_username` varchar(255) DEFAULT NULL,
`oauth_provider` varchar(10) DEFAULT NULL,
`oauth_email` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=3 ;
You should check $model exits first otherwise updateByPk can return 0
if ($model && User::model()->updateByPk($model->id, array("last_login"=> Shared::timeNow())))
Your table does not specify a primary key. Yet you update by primary key.
You have a few choices.
Change your table structure to include a primary key
Use another update method. For example, Update() allow you to pass a criteria object.
Know it's old, but : https://www.php.net/manual/en/pdostatement.rowcount.php
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
And Yii1 use rowCount
Model can be not updated because last_login attribute has not valid value.
Try get model errors ($model->errors()) or check model by $model->validate();
Why you not implement this as follows:
$model->last_login = Shared::timeNow();
if ($model->save())
{
Yii::app()->user->login($identity, $duration);
echo json_encode(array('error' => false, 'success' => url(app()->users->getHomeUrl())));
Yii::app()->end();
}
else {
echo json_encode(array('error' => 'Could not update user info', 'code' => 'auth'));
Yii::app()->end();
}

SQL Hibernate error

I'm using a helper class and trying to insert some data into a db table. I have one self join class with a onetomany relationship.
The main class for the insert transaction
public static void main(String[] args) {
// TODO Auto-generated method stub
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
// Create new checker
Staff checker = new Staff();
checker.setStaffId("d8");
checker.setEmail("do#msn.com");
checker.setName("Doris");
checker.setPassword("890");
checker.setUsername("dr89");
// Create new staff
Staff staff1 = new Staff();
staff1.setStaffId("m6");
staff1.setEmail("mr#msn.com");
staff1.setName("Marius");
staff1.setPassword("234");
staff1.setUsername("mr23");
Staff staff2 = new Staff();
staff2.setStaffId("b8");
staff2.setEmail("be#msn.com");
staff2.setName("Betty");
staff1.setPassword("567");
staff1.setUsername("be56");
Set<Staff> staff = new HashSet<Staff>();
staff.add(staff1);
staff.add(staff2);
staff1.setChecker(checker);
staff2.setChecker(checker);
checker.setSetters(staff);
session.save(checker);
session.save(staff1);
session.save(staff2);
transaction.commit();
}catch (HibernateException e) {
transaction.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
the DB
CREATE TABLE `staff` (
`staff_id` VARCHAR(255) NOT NULL,
`name` VARCHAR(255) NULL DEFAULT NULL,
`username` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`email` VARCHAR(255) NULL DEFAULT NULL,
`checker_id` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`staff_id`),
FOREIGN KEY (`checker_id`) REFERENCES `staff` (`staff_id`));
After I ran the code, it came up with a constraint violation at the column password.
The query and warning in the stacktrace:
Hibernate: select staff_.staff_id, staff_.checker_id as checker6_2_, staff_.email
as email2_, staff_.name as name2_, staff_.password as password2_, staff_.username as
username2_ from staff staff_ where staff_.staff_id=?
Hibernate: select staff_.staff_id, staff_.checker_id as checker6_2_, staff_.email as
email2_, staff_.name as name2_, staff_.password as password2_, staff_.username as
username2_ from staff staff_ where staff_.staff_id=?
Hibernate: insert into staff (checker_id, email, name, password, username, staff_id)
values (?, ?, ?, ?, ?, ?)
Hibernate: insert into staff (checker_id, email, name, password, username, staff_id)
values (?, ?, ?, ?, ?, ?)
Hibernate: insert into staff (checker_id, email, name, password, username,
staff_id)
values (?, ?, ?, ?, ?, ?)
WARN : org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 1048, SQLState:
23000
ERROR: org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Column 'password' cannot
be null
The full error
org.hibernate.exception.ConstraintViolationException: Column 'password' cannot be null
at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
at org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
at $Proxy16.executeUpdate(Unknown Source)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3028)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3469)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:88)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:362)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:354)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:275)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1213)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:402)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at com.project.professional.StaffRelationshipTest.main(StaffRelationshipTest.java:75)
Yes, I set the password in the table to not null, and I have added some data to put it in the main class, so it should not be null. So I'm not sure why the error.
Typo;
Staff staff2 = new Staff();
staff2.setStaffId("b8");
staff2.setEmail("be#msn.com");
staff2.setName("Betty");
staff1.setPassword("567"); << should be staff2
staff1.setUsername("be56"); << should be staff2
Since the password is never set on staff2, the insert (rightly so) fails.

Django: make auth_user.email case-insensitive unique and nullable

I want to make the auth_user.email case-insensitive unique, nullable and default null. The following almost works:
from django.db.models.signals import post_syncdb
import app.models
SQLITE_AUTH_REFORM = [
"PRAGMA writable_schema = 1;",
"""UPDATE SQLITE_MASTER SET SQL =
'CREATE TABLE auth_user (
"id" integer NOT NULL PRIMARY KEY,
"username" varchar(30) NOT NULL UNIQUE,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL,
"email" varchar(75) DEFAULT NULL,
"password" varchar(128) NOT NULL,
"is_staff" bool NOT NULL,
"is_active" bool NOT NULL,
"is_superuser" bool NOT NULL,
"last_login" datetime NOT NULL,
"date_joined" datetime NOT NULL
)' WHERE NAME = 'auth_user';""",
"PRAGMA writable_schema = 0;",
]
def post_syncdb_callback(sender, **kwargs):
from django.db import connections
from django.conf import settings
cursor = connections['default'].cursor()
if 'sqlite' in settings.DATABASES['default']['ENGINE']:
for stmt in SQLITE_AUTH_REFORM:
cursor.execute(stmt)
cursor.execute(
"CREATE UNIQUE INDEX IF NOT EXISTS auth_user_email_unique "
"ON auth_user (email COLLATE NOCASE);"
)
else: # Oracle
cursor.execute(
"CREATE UNIQUE INDEX auth_user_email_unique "
"ON auth_user (upper(email));"
)
cursor.cursor.close()
post_syncdb.connect(post_syncdb_callback, sender=app.models)
I can
User.objects.create(username=str(random.random()), email=None)
To my heart's content. And also,
User.objects.create(username=str(random.random()), email='Foo')
User.objects.create(username=str(random.random()), email='foo')
...
IntegrityError: column email is not unique
The only problems is that the DEFAULT NULL does not seem to work: User.objects.create(username=str(random.random())) creates a user with an empty-string email.
However, in a unit-test, I believe something is going on that prevents the post-syncdb hook from working:
class DjangoUserTest(TestCase):
def test_unique_nullable_email(self):
import IPython; IPython.embed()
u1 = User.objects.create(username="u1", email=None)
u2 = User.objects.create(username="u2", email=None)
I can drop into the ipython shell and see that the table has been apparently modified:
In [1]: from django.db import connection
In [2]: c = connection.cursor()
In [3]: r = c.execute("select `sql` from sqlite_master WHERE tbl_name = 'auth_user';")
In [4]: r.fetchall()
Out[4]:
[(u'CREATE TABLE auth_user (\n "id" integer NOT NULL PRIMARY KEY,\n "username" varchar(30) NOT NULL UNIQUE,\n "first_name" varchar(30) NOT NULL,\n "last_name" varchar(30) NOT NULL,\n "email" varchar(75) DEFAULT NULL,\n "password" varchar(128) NOT NULL,\n "is_staff" bool NOT NULL,\n "is_active" bool NOT NULL,\n "is_superuser" bool NOT NULL,\n "last_login" datetime NOT NULL,\n "date_joined" datetime NOT NULL\n)',),
(None,),
(u'CREATE UNIQUE INDEX auth_user_email_unique ON auth_user (email COLLATE NOCASE)',)]
However, upon trying to do the creates, I get, IntegrityError: auth_user.email may not be NULL. How did this happen when the select sql from sqlite_master WHERE tbl_name = 'auth_user'; clearly says "email" varchar(75) DEFAULT NULL. I feel like I just need to commit the post_syncdb stuff or sth. Any ideas?
UPDATE: No amount of connection.commit(), cursor.close() helps, using TransactionTestCase does not help.