12

I'm having an issue and was hoping that someone could help me out.

My issue is that whenever I run the code in the "MainFile", It outputs the two ID's that it has added the entries at, but then when I view my database I have six entries instead of two... Could anyone tell me why it might be doing this?

Note: I've only supplied snippets of the code from the classes because supplying the full classes would be way too much code. This is the only code be executed though.

CODE IN EDIT HISTORY

Edit: I've added a debug log to the bottom of this post verifying that I'm only executing the SQL code once for each query.

Edit: I'm no longer using the serialization method as it is clearly a bad idea for storing this type of data. However, even with my new code that is storing each individual value within the database I'm still getting three entries instead of one. So, it's the same issue. Anything?

Edit: After a few days of debugging I have narrowed it down to this line that is causing the issue

Throwlite::$systemSQL->executeSql("INSERT into ".SQL_COMMENTTHREADS_TABLE." (id, sort_order) values (DEFAULT, '2')");

You can view the LiteSQL class here for reference: http://pastebin.com/a4C6fF4u

Also, For reference, Here is the code being used to create the Table:

"CREATE TABLE IF NOT EXISTS `" . SQL_COMMENTTHREADS_TABLE . "` (`id` int unsigned NOT NULL AUTO_INCREMENT, `sort_order` int NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;"

And, Even though I'm pretty sure it shouldn't matter, Here is where SQL_COMMENTTHREADS_TABLE is bing defined.

define( 'SQL_COMMENTTHREADS_TABLE', "tl_comment_threads");
Nathan F.
  • 3,250
  • 3
  • 35
  • 69
  • @shA.t It should be pretty obvious that it is PHP, but I've added the tag just in case. Any help at all? – Nathan F. Jun 01 '15 at 04:44
  • I think your problem is not about MySQL behaviors and it is about your PHP code that I can't help you on it ;). – shA.t Jun 01 '15 at 04:56
  • @shA.t It can't be my php though, the only thing I can think of is that the PreparedStatement object is acting abnormally. Because I've verified that the ->execute() line of code is only running one time. – Nathan F. Jun 01 '15 at 05:18
  • you can try adding query comments (http://samlambert.com/posts/the-power-of-query-comments/) then view the query logs - maybe add a counter inside the query comment you should then be able to see where the offending part of the system is... – Ian Wood Jun 01 '15 at 13:31
  • 1
    It is possible that a trigger in the database could cause this behavior. – Gordon Linoff Jun 01 '15 at 14:24
  • I've checked phpMyAdmin, There are absolutely no triggers on any of my databases or tables. I've also enabled logging, and according to mysql it is only executing the query once.... Proof: http://pastebin.com/9e1tFfeK – Nathan F. Jun 02 '15 at 02:30
  • So just to be perfectly clear: looking at the logs you just posted, before the run you had "n" records in your tl_comment_threads table, and now you have "n+6"? – Jerry Andrews Jun 02 '15 at 15:00
  • @JerryAndrews Those logs represent the method "createNewCommentThread()" being called once. Whereas in the above code it is being called twice. So, With the above code i end up with "n+6", but with the code that is outputting that log i posted in my last comment i'm only executing the "createNewCommentThread()" method once, so I end up with "n+3". Hopefully that makes sense. – Nathan F. Jun 02 '15 at 15:08
  • It does. It's clear from the logs posted above (not the transaction logs posted externally) that some process is incrementing the ID field, indicating that you're getting at least 2 insert attempts per insert in your code path. (ID=75, then ID=77). If I had to guess, I'd say there's some other code path in your PHP code that we haven't explored. The inserts aren't happening without some process doing them, so let's see if we can find out who's doing them. Monitoring all queries as shown in this: http://stackoverflow.com/questions/568564/how-can-i-view-live-mysql-queries might help. – Jerry Andrews Jun 02 '15 at 16:32
  • 1
    Do you use a MySQL Cluster Version? I had a similar problems once with a locally installed cluster version (cluster version with all nodes on the same machine for testing purposes). – Hafenkranich Jun 02 '15 at 18:45
  • why the 3 seperate queries? you could just do `insert .. on duplicate key update`. if you insert null into an auto_increment field, mysql will assign a new ID. – Marc B Jun 03 '15 at 21:19
  • @MarcB That wasn't working when I originally tried it, but that's also not the issue. I've made some edits to the question above. I've located the source of the issue, now I just need to figure out what the issue is. – Nathan F. Jun 04 '15 at 01:18
  • You're not also calling `executePreparedStatement()` function, are you? The `executeSQL` is not using prepared statements, but used for executing a single line of SQL (as you have) but your code mentions using prepared statements, which leads me to believer you may also be calling `executePreparedStatement()`: this will also run an insert... – Robbie Jun 04 '15 at 03:06
  • It seems you have some php mess up. The fast way to debug is turn on your mysql query log and run your php, check each statement it sends to mysql. – Tim3880 Jun 04 '15 at 03:35
  • Have you tried to use db transactions? Also check the last inserted id for the duplicate rows. – RunningAdithya Jun 04 '15 at 12:43
  • have you tried to run your INSERT on DB server directly? will it insert one row or three? – alex347 Jun 04 '15 at 15:43
  • @alex347 I tried executing it directly in phpMyAdmin and it only inserted a single row, So it's not something wrong with my database or table. That means it has to be something wrong with the PHP. – Nathan F. Jun 05 '15 at 01:42
  • @Robbie Both the executePreparedStatement and executeSql function are custom made, You can view them in the LiteSQL class posted in the original question. executePreparedStatement gets called from executeSql – Nathan F. Jun 05 '15 at 01:42
  • @Tim3880 I've already turned on the log and verified that this query is only being called once. – Nathan F. Jun 05 '15 at 01:42
  • It's strange. You confirm that the query was called once, and you can also confirm that each query can insert on single row (if run directly), I don't know how to understand it. – Tim3880 Jun 05 '15 at 02:17
  • @shudder Tonight when I am home from work I will make a push to the GitHub repository so that the entire code library is available. It's rather large, but you can then sift through it. I've posted (In the edit history as well as in the question itself) all of the code that I believe is relevant. However, I will post the rest tonight. – Nathan F. Jun 05 '15 at 16:41
  • @thefiscster510 have you tried echoing the $resultset? on line 48. how many times does this line loop? foreach($binds as $key => $value) $tmp[$key] = &$binds[$key]; – Daniel Jun 06 '15 at 14:22
  • Not sure, but though, is there any cache memory? i had an issue with active record cache in CI. – PC. Jun 06 '15 at 19:25
  • 1
    By the way, you are missing a second `}` on line 51 of the pastebin you posted. The `if(sizeof($binds) > 0){` was not closed. – Lux Jun 07 '15 at 01:15
  • @Xenon, You just solved all of the problems.. I have no idea how not only me, but everyone else that has been answering this question has failed to notice that... sometimes programming can be hell.. You can leave that resolve as an answer and I'll give you the bounty.. I'm so angry with myself. Thank you a million. – Nathan F. Jun 07 '15 at 01:24
  • I have made a push to the projects GitHub page where you can view all of the code in the project. Please note that the project is largely unfinished. The code you've been viewing can be found under "classes/system/core/sql/litesql.class.php" and "classes/system/comments/". The only file being executed in this test is the "tester.php" file located in the root directory of the project. https://github.com/thefiscster510/ThrowLite – Nathan F. Jun 07 '15 at 02:23
  • After running this on another system, I've realized that is has something to do with my WAMP installation or configuration. I've tried wiping my WAMP installation and reinstalling with no success. Any suggestions? – Nathan F. Jun 07 '15 at 19:11
  • I just tried uninstalling WAMP and installing XAMPP instead, so as far as I know that means it should be running on a completely clean configuration. However, I'm still getting the same issue where three entries are getting inserted instead of just one. This makes absolutely no sense to me since I ran this exact same code on two other machines running clean installations of WAMP and it only inserted one entry.. – Nathan F. Jun 07 '15 at 20:05
  • Github code insert worked fine on my machine (needed to add commentthread table constants - name/schema). It's quite unmaintainable for an unfinished project (global states all over). Try something easier for a start, so it was still possible to improve it from architectural pov. Lots of unproductive work there. – shudder Jun 10 '15 at 14:00
  • @shudder I was also able to get it working on a few other machines. The problem I was having I feel was somewhere in my sql configuration. I reinstalled wamp to see if that would fix it, and it didn't, I then tried installing xampp in place of wamp and it still didn't fix it.. But judging by the amount of debugging I've done thus far, I'm pretty confident that it's happening somewhere in my sql configuration. – Nathan F. Jun 11 '15 at 19:48

5 Answers5

1

I'm not sure this answers your question, but you seem to be specifying the ID that you are inserting. I'm not sure whether you aren't using a PRIMARY KEY on your id column or why this works at all, but maybe you want this:

INSERT INTO " . SQL_COMMENTS_TABLE . " (id, thread) VALUES (DEFAULT, ?)

tumultous_rooster
  • 12,150
  • 32
  • 92
  • 149
Jonathan Card
  • 122
  • 1
  • 8
  • Also, why are you specifying the ID is a string (with the "ss") when it seems to be a number? I assume the rows have AUTO_INCREMENT if you are using GetLastInsertID – Jonathan Card Jun 03 '15 at 21:11
  • Honestly, As far as the "SS" part goes, I wasn't thinking when I did it but I hadn't had any issues with it. I should change that though, And now that it's been brought to my attention I will once I'm home from work. As far as the PRIMARY KEY goes, I do have ID set as the primary Key. I'm going to try a few more things out tonight including your proposed solution and I'll let you know how it goes. – Nathan F. Jun 03 '15 at 21:35
  • I've made a few edits to my question above. I've narrowed down the source of the issue, I just need to figure out what the issue actually is. If you could look at the question above for the new details and weigh in, that'd be awesome. Thanks. – Nathan F. Jun 04 '15 at 01:19
  • I have made a push to the projects GitHub page where you can view all of the code in the project. Please note that the project is largely unfinished. The code you've been viewing can be found under "classes/system/core/sql/litesql.class.php" and "classes/system/comments/". The only file being executed in this test is the "tester.php" file located in the root directory of the project. https://github.com/thefiscster510/ThrowLite – Nathan F. Jun 07 '15 at 02:24
  • After running this on another system, I've realized that is has something to do with my WAMP installation or configuration. I've tried wiping my WAMP installation and reinstalling with no success. Any suggestions? – Nathan F. Jun 07 '15 at 19:11
  • This seems like a silly suggestion, but could check with "SHOW MASTER STATUS" or "SHOW SLAVE STATUS" and see if you're replicating to yourself? – Jonathan Card Jun 07 '15 at 19:33
  • where would those be found? – Nathan F. Jun 07 '15 at 19:45
  • I just tried uninstalling WAMP and installing XAMPP instead, so as far as I know that means it should be running on a completely clean configuration. However, I'm still getting the same issue where three entries are getting inserted instead of just one. This makes absolutely no sense to me since I ran this exact same code on two other machines running clean installations of WAMP and it only inserted one entry.. – Nathan F. Jun 07 '15 at 19:52
  • They're run from a SQL client, but it was a dumb suggestion. They would have replicated the id and gotten a duplicate key error. Probably not legal, anyway. – Jonathan Card Jun 07 '15 at 20:02
0

When updating UPDATE tl_comments SET thread=? WHERE id = ? and the second ? is not replaced with a valid existing id but instead remains empty, the database can't find an entry to update and inserts a new row instead. Thus creating another entry wich leads you to generating 2 rows instead of just one every time you query.

Which means the GetLastInsertID() function is not working properly. This can be caused by a few things but there are already many helpful hints to that question around at stackoverflow.

Hafenkranich
  • 1,696
  • 18
  • 32
  • 1
    I will check this out when I get home from work tonight. But, I'm pretty sure I've already verified that I am pulling the right ID with GetLastInsertID(). I'll let you know tonight when I'm home. – Nathan F. Jun 02 '15 at 20:00
  • After researching into this, I've verified that the GetLastInsertId() method is working properly. Here is a copy of the complete LiteSQL Class: http://pastebin.com/a4C6fF4u It is initialized in the main file by doing ThrowLite::$systemSQL = new LiteSQL(); – Nathan F. Jun 02 '15 at 22:57
  • Raphael, are you sure that LiteSql make INSERT if can't make UPDATE? (thanks, thefiscster510). – Mykola Vasilaki Jun 03 '15 at 06:35
  • Try adding `OR IGNORE` like in `UPDATE OR IGNORE ... INSERT OR IGNORE ...` – Hafenkranich Jun 03 '15 at 13:35
  • There is a very good explanation [here](http://stackoverflow.com/questions/15277373/sqlite-upsert-update-or-insert) – Hafenkranich Jun 03 '15 at 13:36
  • @RaphaelWeber When I add OR INGORE to the Query, the query will not run. I've yet to get home and check what the error is when trying to run that query, but i'll let you know as soon as I do. Also, I've made a few edits to my question above. I've narrowed down the source of the issue, I just need to figure out what the issue actually is. If you could look at the question above for the new details and weigh in, that'd be awesome. Thanks. – Nathan F. Jun 04 '15 at 01:20
  • I have made a push to the projects GitHub page where you can view all of the code in the project. Please note that the project is largely unfinished. The code you've been viewing can be found under "classes/system/core/sql/litesql.class.php" and "classes/system/comments/". The only file being executed in this test is the "tester.php" file located in the root directory of the project. https://github.com/thefiscster510/ThrowLite – Nathan F. Jun 07 '15 at 02:24
  • After running this on another system, I've realized that is has something to do with my WAMP installation or configuration. I've tried wiping my WAMP installation and reinstalling with no success. Any suggestions? – Nathan F. Jun 07 '15 at 19:11
  • I just tried uninstalling WAMP and installing XAMPP instead, so as far as I know that means it should be running on a completely clean configuration. However, I'm still getting the same issue where three entries are getting inserted instead of just one. This makes absolutely no sense to me since I ran this exact same code on two other machines running clean installations of WAMP and it only inserted one entry.. – Nathan F. Jun 07 '15 at 20:05
  • And you are 100% sure, GetLastInsertId() returns an ID (not just 1) everytime on this maschine? Because depending on the maschine/Infrastructure that sadly sometimes just doesn't work. – Hafenkranich Jun 08 '15 at 02:43
0

I could not locate any logical issue in the code snippet provided by you. However can you make following changes and post the output here :

  1. Add a getter for "prepared_statements" member variable.
  2. After your insert query finished running, print out output of above getter function.

The way this DB access class is written, it is evident there is no way two insert query can exists in single index of the "prepared_statements" array. Still it is better to check and confirm. Also if you can share the function (under which insert query piece of code is running) and the code snippet from where this function is called can be useful for others to debug the problem.

joy d
  • 408
  • 2
  • 13
  • I have made a push to the projects GitHub page where you can view all of the code in the project. Please note that the project is largely unfinished. The code you've been viewing can be found under "classes/system/core/sql/litesql.class.php" and "classes/system/comments/". The only file being executed in this test is the "tester.php" file located in the root directory of the project. https://github.com/thefiscster510/ThrowLite – Nathan F. Jun 07 '15 at 02:24
  • After running this on another system, I've realized that is has something to do with my WAMP installation or configuration. I've tried wiping my WAMP installation and reinstalling with no success. Any suggestions? – Nathan F. Jun 07 '15 at 19:10
0

I feel somewhere in your code a loop is running which is causing inserting it multiple times in the database. Can you try echo your query so that u get to know how many times your query is running.

Another hack can be put condition to check whether row already present- do not insert.

Can you please post your code so that I can debug it.

rajatsaurastri
  • 653
  • 3
  • 21
  • Tonight when I am home from work I will make a push to the GitHub repository so that the entire code library is available. It's rather large, but you can then sift through it. I've posted (In the edit history as well as in the question itself) all of the code that I believe is relevant. However, I will post the rest tonight. – Nathan F. Jun 05 '15 at 16:41
  • I have made a push to the projects GitHub page where you can view all of the code in the project. Please note that the project is largely unfinished. The code you've been viewing can be found under "classes/system/core/sql/litesql.class.php" and "classes/system/comments/". The only file being executed in this test is the "tester.php" file located in the root directory of the project. https://github.com/thefiscster510/ThrowLite – Nathan F. Jun 07 '15 at 02:23
  • After running this on another system, I've realized that is has something to do with my WAMP installation or configuration. I've tried wiping my WAMP installation and reinstalling with no success. Any suggestions? – Nathan F. Jun 07 '15 at 19:10
  • I just tried uninstalling WAMP and installing XAMPP instead, so as far as I know that means it should be running on a completely clean configuration. However, I'm still getting the same issue where three entries are getting inserted instead of just one. This makes absolutely no sense to me since I ran this exact same code on two other machines running clean installations of WAMP and it only inserted one entry.. – Nathan F. Jun 07 '15 at 20:05
  • In your /classes/system/comments/core/commentsystem.class.php You are using Throwlite::$systemSQL->executeSql("INSERT into ".SQL_COMMENTTHREADS_TABLE." (id, sort_order) values (DEFAULT, '2')"); so where you have defined $systemSQL object ? you can directly call your executeSql function ? can you please try also can you print your bind array ? – rajatsaurastri Jun 08 '15 at 07:28
  • The binds array being passed is completely empty for this specific query. Also, The $systemSQL variable is defined in /classes/system/core/throwlite.class.php at the very bottom. – Nathan F. Jun 08 '15 at 23:09
0

By the way, you are missing a second } on line 51 of the pastebin you posted. The if(sizeof($binds) > 0){ was not closed.

Lux
  • 1,540
  • 1
  • 22
  • 28
  • I'm so sorry about this, but after leaving my comment and trying a few more times I realized it's still having the issue. However, it shows one entry, and then I reload phpMyAdmin and the other two are magically there.. – Nathan F. Jun 07 '15 at 01:45
  • Sorry I can't be of more use. – Lux Jun 07 '15 at 01:47
  • I have made a push to the projects GitHub page where you can view all of the code in the project. Please note that the project is largely unfinished. The code you've been viewing can be found under "classes/system/core/sql/litesql.class.php" and "classes/system/comments/". The only file being executed in this test is the "tester.php" file located in the root directory of the project. https://github.com/thefiscster510/ThrowLite – Nathan F. Jun 07 '15 at 02:23
  • After running this on another system, I've realized that is has something to do with my WAMP installation or configuration. I've tried wiping my WAMP installation and reinstalling with no success. Any suggestions? – Nathan F. Jun 07 '15 at 19:10
  • I just tried uninstalling WAMP and installing XAMPP instead, so as far as I know that means it should be running on a completely clean configuration. However, I'm still getting the same issue where three entries are getting inserted instead of just one. This makes absolutely no sense to me since I ran this exact same code on two other machines running clean installations of WAMP and it only inserted one entry.. – Nathan F. Jun 07 '15 at 20:05