{"id":81,"date":"2020-02-29T21:30:16","date_gmt":"2020-03-01T02:30:16","guid":{"rendered":"https:\/\/home.huizhao.ca\/?p=81"},"modified":"2020-02-29T21:30:17","modified_gmt":"2020-03-01T02:30:17","slug":"migrating-php-code-from-mysql-to-sqlite-the-basics","status":"publish","type":"post","link":"https:\/\/huizhao.ca\/?p=81","title":{"rendered":"MIGRATING PHP CODE FROM MYSQL TO SQLITE, THE BASICS"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Data types<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">MySQL<\/h4>\n\n\n\n<p>There\u2019s a shitload of data types, really, just go look at the official documentation and bask in the glory of MySQL redundancy (j\/k).<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">SQLite<\/h4>\n\n\n\n<p>Very few, reassuring and simple data types. Basically text, numbers, and \u201cwhatever\u201d (blob). Again, go look at the official documentation.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Database connection<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">MySQL<\/h4>\n\n\n\n<p><code>$GLOBALS[\"dbcon\"]=@mysqli_connect($dbhost, $dbuser, $dbpass);<\/code><br><code>if (mysqli_error($GLOBALS[\"dbcon\"])) die(\"errore connessione db\");<\/code><br><code>@mysqli_select_db($GLOBALS[\"dbcon\"],$dbname);<\/code><br><code>if (mysqli_error($GLOBALS[\"dbcon\"])) die(\"errore connessione db\");<\/code><br><code>@mysqli_set_charset($GLOBALS[\"dbcon\"],'utf8');<\/code><br><code>if (mysqli_error($GLOBALS[\"dbcon\"])) die(\"errore connessione db\");<\/code><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">SQLite<\/h4>\n\n\n\n<p><code>$db = new SQLite3(dirname(__FILE__).\"\/DB\/db.sqlite\");<\/code><br><code>$db-&gt;busyTimeout(5000);<\/code><br><code>\/\/ WAL mode has better control over concurrency.<\/code><br><code>\/\/ Source: https:\/\/www.sqlite.org\/wal.html<\/code><br><code>$db-&gt;exec('PRAGMA journal_mode = wal;');<\/code><br><code>$db-&gt;exec('PRAGMA synchronous=NORMAL;');<\/code><\/p>\n\n\n\n<p>(last couple of rows are only useful if you plan to have some -little- write-concurrency, otherwise don\u2019t use them)<\/p>\n\n\n\n<p>Very important thing to know: if you are writing code for a local-running application, SQLite connections will not \u201ctime out\u201d as there\u2019s no server to wait for your input, just a file on the disk (or memory, even!)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Queries<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">MySQL<\/h4>\n\n\n\n<p><code>$results=mysqli_query($GLOBALS[\"dbcon\"],$query);<\/code><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">SQLite<\/h4>\n\n\n\n<p><code>$db-&gt;exec($query);<\/code><\/p>\n\n\n\n<p>when you don\u2019t expect results, so for&nbsp;<code>INSERT<\/code>,&nbsp;<code>UPDATE<\/code>&nbsp;or&nbsp;<code>DELETE<\/code><\/p>\n\n\n\n<p><code>$results=$db-&gt;query($query);<\/code><\/p>\n\n\n\n<p>when you expect&nbsp;<strong>multiple<\/strong>&nbsp;results, or several fields in a row<\/p>\n\n\n\n<p><code>$value=$db-&gt;singleQuery($query);<\/code><\/p>\n\n\n\n<p>when you want returned a single-value result, for example when the query is something like&nbsp;<code>SELECT timestamp FROM records WHERE id=$number LIMIT 1&nbsp;<\/code>(for this, with MySQL, you should parse the results with&nbsp;<code>mysqli_fetch_array<\/code>&nbsp;or similar, and then select the first value with&nbsp;<code>[0]<\/code>)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fetch results<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">MySQL<\/h4>\n\n\n\n<p><code>$row=mysqli_fetch_array($results);<\/code><\/p>\n\n\n\n<p>when you want both associative and indexed arrays,<\/p>\n\n\n\n<p><code>$row=mysqli_fetch_assoc($results);<\/code><\/p>\n\n\n\n<p>when you only need associative arrays, and<\/p>\n\n\n\n<p><code>$row=mysqli_fetch_row($results);<\/code><\/p>\n\n\n\n<p>if you want only indexed arrays.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">SQLite<\/h4>\n\n\n\n<p>In parallel with above:<\/p>\n\n\n\n<p><code>$row=$results-&gt;fetchArray();<\/code><\/p>\n\n\n\n<p><code>$row=$results-&gt;fetchArray(SQLITE3_ASSOC);<\/code><\/p>\n\n\n\n<p><code>$row=$results-&gt;fetchArray(SQLITE3_NUM);<\/code><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Speed considerations<\/h4>\n\n\n\n<p>If you don\u2019t need associative arrays, you should always go for indexed arrays, since both in MySQL and SQLite they are fetched significantly faster; also, even if by very little, fetching only associative arrays is still faster then having both associative and indexed fetched together (and you\u2019re not going to need those both anyway).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Escaping<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\">MySQL<\/h4>\n\n\n\n<p><code>mysqli_real_escape_string($GLOBALS[\"dbcon\"],$string);<\/code><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">SQLite<\/h4>\n\n\n\n<p><code>SQLite3::escapeString($string);<\/code><\/p>\n\n\n\n<p>this function is not binary safe though at the time of writing (hasn\u2019t been for a while from what I understand\u2026)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Database functions<\/h2>\n\n\n\n<p>Just converting the PHP functions won\u2019t be sufficient for most.<\/p>\n\n\n\n<p>Think about time functions for examples, or&nbsp;<code>DEFAULT<\/code>&nbsp;values, or&nbsp;<code>NULL<\/code>ing a&nbsp;<code>NOT NULL<\/code>&nbsp;timestamp column to have it automatically assigned to&nbsp;<code>CURRENT_TIMESTAMP<\/code>, these things are not present in SQLite.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">MySQL<\/h4>\n\n\n\n<p><code>DEFAULT CURRENT_TIMESTAMP<\/code><\/p>\n\n\n\n<p><code>NOW()<\/code>,&nbsp;<code>YEAR()<\/code>,&nbsp;<code>TIMEDIFF()<\/code>, and another shitload of functions.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">SQLite<\/h4>\n\n\n\n<p><code>DEFAULT (Datetime('now','localtime'))<\/code><\/p>\n\n\n\n<p>Several variations on the&nbsp;<code>strftime()<\/code>&nbsp;functions, of which the&nbsp;<code>Datetime()<\/code>&nbsp;above is an example.<\/p>\n\n\n\n<p>Again, go look at the official documentation, as what you see above is my own translation for my own purposes, and you will find both in official sources and in the vast world of StackOverflow a plethora of readings and interpretations.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Data types MySQL There\u2019s a shitload of data types, really, just go look at the official documentation and bask in the glory of MySQL redundancy (j\/k). SQLite Very few, reassuring and simple data types. Basically text, numbers, and \u201cwhatever\u201d (blob). Again, go look at the official documentation. Database connection MySQL $GLOBALS[&#8220;dbcon&#8221;]=@mysqli_connect($dbhost, $dbuser, $dbpass);if (mysqli_error($GLOBALS[&#8220;dbcon&#8221;])) die(&#8220;errore &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/huizhao.ca\/?p=81\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;MIGRATING PHP CODE FROM MYSQL TO SQLITE, THE BASICS&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-81","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/huizhao.ca\/index.php?rest_route=\/wp\/v2\/posts\/81","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/huizhao.ca\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/huizhao.ca\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/huizhao.ca\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/huizhao.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=81"}],"version-history":[{"count":1,"href":"https:\/\/huizhao.ca\/index.php?rest_route=\/wp\/v2\/posts\/81\/revisions"}],"predecessor-version":[{"id":82,"href":"https:\/\/huizhao.ca\/index.php?rest_route=\/wp\/v2\/posts\/81\/revisions\/82"}],"wp:attachment":[{"href":"https:\/\/huizhao.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=81"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/huizhao.ca\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=81"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/huizhao.ca\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=81"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}