Symfony Doctrine Flush Returning Null - symfony

I'm trying to create a system that will recreate a new shift when given a date array example [0,3,4] for the same day, 3 days away and 4 days away. When I create a single shift I am able to persist and flush to the database with no problem at all.
My Issue is when I create my $newShifts in a forloop persist them and once all are persisted (9 for example) I go to flush and get the following.
An exception occurred while executing 'INSERT INTO guard_shift (shift_start, shift_end, actual_shift_start, actual_shift_end, approved, deletedAt, user_id, admin_id, site_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)' with params [null, null, null, null, false, null, 1, 1, 8]:\n\nSQLSTATE[23000]: Integrity constraint violation: 1048 Column 'shift_start' cannot be null",
"class": "Doctrine\\DBAL\\Exception\\NotNullConstraintViolationException
If I dd $newShift->getStartShift before the flush I get 9 start times.
This Gist is both the controller endpoint and my helper combined in one file for ease of sharing.
https://gist.github.com/George-Farrell/86524c53f3218dbd1cbfd003b7666df6

The code in the gist looks very raw and needs refactoring to more obvious steps and more small functions for the sake of readability.
My suggestion is that this function is the root of the problem:
when $clashingId is true, you can't persist a new shift, because the result of the function is already returned.
private function flushShift($admin,$shiftStart,$shiftFinish,$user,$site)
{
$newShift = new GuardShift();
$newShift->setAdmin($admin);
$newShift->setShiftStart($this->timestamp->reverseTransform(strtotime($shiftStart)));
$newShift->setShiftEnd($this->timestamp->reverseTransform(strtotime($shiftFinish)));
$newShift->setUser($user);
$newShift->setSite($site);
$clashingId = $this->isShiftClashing(
$shiftStart,
$shiftFinish,
$admin,
$user
);
if ($clashingId == true) {
$clash = $this->entityManager->getRepository(GuardShift::class)->findOneBy(['id' => $clashingId]);
$data = $this->serialize->serialize($clash, 'json', SerializationContext::create()->enableMaxDepthChecks());
return new JsonResponse($data, Response::HTTP_CONFLICT, [], true);
}
$this->entityManager->persist($newShift);
}

Related

Using WHERE NOT EXISTS in Sqlite returns syntax error

(This relates to a Discord bot using Discord.js and sqlite v3, NOT sqlite3)
I'm currently trying to use WHERE NOT EXISTS to add a row to my Sqlite table, but only if there isn't a row where "serverid" is the ID of the current server and the type spam already.
I tried it with this:
sql.run(`INSERT INTO filters WHERE NOT EXISTS(SELECT 1 FROM filters WHERE serverid = "${msg.guild.id}" AND type = "Spam") (serverid, type, active, action, time) VALUES (?, ?, ?, ?, ?)`, msg.guild.id, `Spam`, 0, `delete`, 60)
This works if there ISN'T a row with that ID and type yet, but as soon as it does exist, I get a "syntax error at: WHERE".
It doesn't tell me which WHERE the problem is, and I double checked the syntax multiple times and it should be fine.
Does this not work in sqlite? Or did I get the syntax wrong?
The syntax of the query is wrong.
You should use INSERT ... SELECT instead of INSERT ... VALUES:
INSERT INTO filters (serverid, type, active, action, time)
SELECT ?, ?, ?, ?, ?
WHERE NOT EXISTS(SELECT 1 FROM filters WHERE serverid = "${msg.guild.id}" AND type = "Spam")`

In SQLite, showing missmatch even number of '?' s in statement string is equal to the number of argument count

While trying to insert the multiple records in SQLite, even passing same number of argument as ? in INSERT statement, but its giving error with the message of mismatch of number of argument and '?'s in INSERT statement.
Code for Multiple insertion in SQLite
var query01 = "INSERT INTO TBL_JCI_CONTENT (slug, title, content) VALUES ";
var insertdata = [];
var rowArgs = [];
home_content.forEach(function (category) {
rowArgs.push('( ?, ?, ? )');
insertdata.push(category.slug);
insertdata.push(category.title);
insertdata.push(category.content);
});
query01 += rowArgs.join(', ');
console.log(query01);
console.log(insertdata);
$cordovaSQLite.execute(db, query01, [insertdata]).then(function(res) {
console.log('Successfully Inserted Home Content');
}, function (err) {
console.error(err);
});
While running this code I am getting following error:
Object {home_page: Array[6]}
controllers.js:83 INSERT INTO TBL_JCI_CONTENT (slug, title, content) VALUES ( ?, ?, ? ), ( ?, ?, ? )
Array[6]
0: “home”
1: “Home”
2: “HMI is a nonprofit “
3: "mission"
4: "Mission"
5: "We develop the skills
length: 6__proto__: Array[0]
controllers.js:89 SQLError {code: 5, message: "number of '?'s in statement string does not match argument count"}
Refer many stackflow answers but couldn't get the solution way around.

(No such column).. But, it's there

Here's my tables:
CREATE TABLE IF NOT EXISTS message_threads (
thread_id integer primary key autoincrement NOT NULL,
user_id integer NOT NULL,
last_checked timestamp NOT NULL DEFAULT '0',
last_updated timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
)
CREATE TABLE IF NOT EXISTS messages (
message_id integer primary key autoincrement NOT NULL,
thread_id integer NOT NULL,message_type integer NOT NULL DEFAULT '0',
message_content varchar(500) NOT NULL,
message_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
sent integer NOT NULL DEFAULT '0'
);
Here's the error I'm getting:
Could not prepare statement (1 no such column: m.message_date)
Here's the query that I'm using (This query works in MySQL, as I tested it in PHPMyAdmin with a dummy table)
SELECT * FROM messages m, message_threads t
WHERE m.thread_id = t.thread_id
ORDER BY t.last_updated, t.thread_id, m.message_date;
I'm using WebSQL (which I think is SQLite)
FULL WebSQL CODE
$rootScope.database = openDatabase('application.db', '1.0', 'Application database', 1024 * 1024);
$rootScope.database.transaction(function(tx) {
tx.executeSql("CREATE TABLE IF NOT EXISTS message_threads (thread_id integer primary key autoincrement NOT NULL, user_id integer NOT NULL, last_checked timestamp NOT NULL DEFAULT '0', last_updated timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP);");
tx.executeSql("CREATE TABLE IF NOT EXISTS messages (message_id integer primary key autoincrement NOT NULL,thread_id integer NOT NULL,message_type integer NOT NULL DEFAULT '0',message_content varchar(500) NOT NULL, message_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, sent integer NOT NULL DEFAULT '0');");
});
// Empty messages/threads for testing purposes
$rootScope.database.transaction(function(tx) {
tx.executeSql("DELETE FROM messages;");
tx.executeSql("DELETE FROM message_threads;");
});
$rootScope.database.transaction(function(tx) {
tx.executeSql("INSERT INTO message_threads (user_id) VALUES (?);", [0]);
tx.executeSql("INSERT INTO messages (thread_id, message_content, sent) VALUES (?, ?, ?);", [1, "How are you doing?", 1]);
tx.executeSql("INSERT INTO messages (thread_id, message_content) VALUES (?, ?);", [1, "Good you?"]);
});
$rootScope.database.transaction(function(tx) {
tx.executeSql("SELECT * FROM messages m, message_threads t WHERE m.thread_id = t.thread_id ORDER BY t.last_updated, t.thread_id, m.message_date", [], function(tx, rs) {
console.log(JSON.stringify(rs));
}, function(tx, err) {
alert("Error: " + err.message);
});
});
I should add that the query works fine using DBBrowser for SQLite.
Chances are that your database has an older version of the table without the column.
CREATE TABLE IF NOT EXISTS only creates a new table with the given specification if a table by the same name does not exist. It does nothing to make sure the columns are there.
To fix it, either remove your database file, or use DROP TABLE to get rid of your old tables before recreating them.
I have created a fresh new sqlite database and tested both of your create queries using the plain command line sqlite.exe version 3.8.0.2 on windows 7. There were no errors.
Then I have used SQLiteStudio Version 3.0.6 and entered some dummy data and executed your select query. Again no issues.
The tools that I have used can only deal with sqlite. Therefore, it seems to me that there are some configuration issues with your tools.

Creating test objects in RSpec with FactoryGirl fails with Nested Attributes

I have a Workout model that has many PerformedExercises, which has many PeformedSets. I can't get it to build an object in my test and I am not sure if it's SQLite3, or something else (it works fine outside of the testing environment).
I have the following factories:
FactoryGirl.define do
factory :workout do
title 'workout one'
performed_exercise
end
factory :performed_exercise do
exercise_id '2'
performed_set
end
factory :performed_set do
set_number '1'
end
end
My RSpec test looks like so (I've made it real simple so as to rule out any other issues inside the test):
it "is causing me to lose hair" do
wrkt = FactoryGirl.build(:workout)
end
When I run the test, I get the following error message:
Failure/Error: wrkt = FactoryGirl.build(:workout)
ActiveRecord::StatementInvalid:
SQLite3::ConstraintException: constraint failed:
INSERT INTO "performed_sets" ("created_at", "notes", "performed_exercise_id", "reps", "set_number", "updated_at", "weight")
VALUES (?, ?, ?, ?, ?, ?, ?)
Any help would be greatly appreciated!
Don't set the exercise id. Let SQLite handle the id's for you.
factory :performed_exercise do
performed_set
end

SQLite error: 'could not convert text value to numeric value.'

I've found a work-around, but I am completely perplexed by an issue I ran into with Adobe Air and SQLite. An UPDATE query that I believe worked correctly earlier in the development process suddenly started failing with the error details:'could not convert text value to numeric value.', operation:'execute', detailID:'2300'. Several hours later I found that if I included a pretty irrelevant column in the query, setting it to an arbitrary value, the problem went away. As luck would have it, this did not affect the business logic in any meaningful way, so I'm going to leave it as is. However, I detest mysteries like this. Can anyone think of what might have happened?
(Edit: Sorry, I made a mistake in my code. The last two queries were identical in my original post. In fact, the UPDATE query only worked when I also added locked = null or locked = 0 to the query. If I didn't set this value, the query would fail. I did just about everything I could to get around this, including rebuilding the database file.)
Here's the table definition:
CREATE TABLE cars (
car_id INTEGER PRIMARY KEY AUTOINCREMENT DEFAULT NULL,
cargroup_id NUMERIC,
starting_ordinal NUMERIC,
ending_ordinal NUMERIC,
locked NUMERIC
);
This query has always worked:
var query = new Query(
"UPDATE cars SET locked = (car_id = ?) WHERE cargroup_id = ?",
[intCarId,intCargroupId],
success,failure
);
This query failed with the above error ([edit]):
var query = new Query(
"UPDATE cars SET starting_ordinal = ?, ending_ordinal = ?, cargroup_id = ? WHERE car_id = ?",
[
parseInt(objPayout.starting_ordinal,10),
parseInt(objPayout.ending_ordinal,10),
parseInt(objPayout.cargroup_id,10),
parseInt(objPayout.car_id,10)
],
success,failure
);
I solved the problem by changing the query to this:
var query = new Query(
"UPDATE cars SET starting_ordinal = ?, ending_ordinal = ?, cargroup_id = ?, locked = null WHERE car_id = ?",
[
parseInt(objPayout.starting_ordinal,10),
parseInt(objPayout.ending_ordinal,10),
parseInt(objPayout.cargroup_id,10),
parseInt(objPayout.car_id,10)
],
success,failure
);

Resources