<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQLite &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/sqlite/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 18 Aug 2025 20:40:26 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Introduction to PocketBase: A Backend Alternative for Xojo Developers</title>
		<link>https://blog.xojo.com/2025/02/19/introduction-to-pocketbase-a-backend-alternative-for-xojo-developers/</link>
		
		<dc:creator><![CDATA[Ezekiel Burke]]></dc:creator>
		<pubDate>Wed, 19 Feb 2025 16:02:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PocketBase]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=14488</guid>

					<description><![CDATA[Introduction When developing applications with Xojo, choosing the right backend is crucial for managing data efficiently. Traditionally, Xojo developers rely on SQL databases such as&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p>When developing applications with Xojo, choosing the right backend is crucial for managing data efficiently. Traditionally, Xojo developers rely on SQL databases such as SQLite, MySQL, or PostgreSQL for their desktop, web, and mobile applications. However, there is an alternative that provides a more flexible and modern approach to backend development: <a href="https://pocketbase.io/" target="_blank" rel="noreferrer noopener">PocketBase</a>.</p>



<p>PocketBase is an open-source backend perfect for your multi-platform Xojo application. It offers a simple-to-use API and a built-in admin panel to manage the data from any web browser. No other tool such as MySQL, Workbench, or SQL Studio is needed. In this post, I will explain how it compares to traditional SQL databases and demonstrate how to integrate it into a Xojo project.</p>



<h3 class="wp-block-heading">Why Choose PocketBase for Your Xojo App Backend?</h3>



<p>PocketBase is a lightweight, self-hosted backend designed for simplicity and flexibility. Unlike traditional SQL databases that require a separate backend service or API layer, PocketBase is an all-in-one solution that combines the database and API.</p>



<h3 class="wp-block-heading">Key Features:</h3>



<p>Embedded Database – Powered by SQLite, eliminating the need for a separate database server.</p>



<p>Built-in User Authentication – Supports email/password logins, OAuth2 sign-ups, and one-time password (OTP) with minimal setup.</p>



<p>File Storage – Store and retrieve files locally or via S3.</p>



<p>Cross-Platform Compatibility – Runs on macOS, Windows, and Linux. Can communicate via URLConnection making it ideal for Xojo’s desktop, web, and mobile platforms.</p>



<p>Easy Deployment – A single binary file that can be self-hosted or deployed anywhere with minimal configuration.</p>



<h2 class="wp-block-heading">Setting Up PocketBase for a Xojo App</h2>



<p>To get started, I have simplified some steps below. If you get stuck or want more in-depth instructions take a look at the <a href="https://pocketbase.io/docs/" target="_blank" rel="noreferrer noopener">documentation</a>.</p>



<ul class="wp-block-list">
<li>Download PocketBase
<ul class="wp-block-list">
<li>Visit <a href="https://pocketbase.io/" target="_blank" rel="noreferrer noopener">PocketBase</a> and download the latest release for your operating system.</li>



<li>Extract the files to your project directory.</li>
</ul>
</li>



<li>Run PocketBase
<ul class="wp-block-list">
<li>Start the PocketBase server by navigating to the extracted folder in the command prompt/terminal.</li>



<li>Run the command: <code>./pocketbase serve</code> to start the server.</li>
</ul>
</li>



<li>Access the Admin Panel
<ul class="wp-block-list">
<li>Open <code>http://127.0.0.1:8090/_/</code> in a web browser and set up an admin account.</li>
</ul>
</li>



<li>Add a User
<ul class="wp-block-list">
<li>In the PocketBase admin panel, create a new record in the users collection. (Collections are the equivalent of a table in SQL.)</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">Connect Xojo to PocketBase</h2>



<p>Now that your PocketBase server is running, integrate authentication into your Xojo desktop app. In this example, we will handle authentication in the open event of the main window. This will demonstrate how Xojo interacts with PocketBase’s authentication API.</p>



<h3 class="wp-block-heading">Implement the Login Request</h3>



<p>Add the following code to the open event of your main window:</p>



<pre class="wp-block-code"><code>Var userEmail As String = "email@email.com"
Var userPassword As String = "MyPassword!"
Var loginURL As String = "http://127.0.0.1:8090" + "/api/collections/users/auth-with-password"
Var conn As New URLConnection
conn.RequestHeader("Content-Type") = "application/json"
 
Var loginPayload As New JSONItem
loginPayload.Value("identity" ) = userEmail
loginPayload.Value("password") = userPassword
conn.SetRequestContent(loginPayload.ToString, "application/json")
 
Var loginResponse As String = conn.SendSync("POST", loginURL)
Var jsonResponse As New JSONItem(loginResponse)
Var userInfo As JSONItem = jsonResponse.Lookup("record", New JSONItem)
Var userID As String = userInfo.Lookup("id", "")
Var authToken As String = jsonResponse.Lookup("token", "")
 
If authToken.Length > 0 Then
  MessageBox("Login successful! Welcome, User ID: " + userID)
Else
  MessageBox("Login failed. Please check your credentials.")
End If</code></pre>



<h3 class="wp-block-heading">Update Your Credentials and URL</h3>



<p>Replace userEmail and userPassword with the credentials you used to create a user in PocketBase. Also, ensure the loginURL matches your PocketBase instance (without <code>/_/</code> at the end).</p>



<h3 class="wp-block-heading">Run The App</h3>



<p>Launch your Xojo app. If authentication is successful, a message box will display the user&#8217;s ID. Otherwise, you will see an error message indicating that the credentials are incorrect.</p>



<h3 class="wp-block-heading">Wrapping Up</h3>



<p>In this article, you have successfully set up a PocketBase server, created a record, and integrated authentication into your Xojo app. PocketBase simplifies backend development by handling authentication and data storage—all without the need for a traditional SQL database.</p>



<p>With PocketBase, there is no need to set up complex user tables, hash passwords, or build a custom API. Collections can be easily managed directly from the web via the admin panel. This means you can spend less time managing infrastructure and more time focusing on bringing your app to market.</p>



<p>To help you get started, I’ve created a collection of example projects, which you can find here:</p>



<p><a href="https://github.com/Iron-Elephant-Solutions/Xojo-Pocketbase-Examples">Xojo-Pocketbase-Examples</a></p>



<p>If you’d like to discuss how Iron Elephant Solutions has used Xojo and PocketBase in real-world applications, feel free to reach out through our <a href="https://ironelephantsolutions.com/">website</a> or add me on <a href="https://www.linkedin.com/in/ezekiel-zeke-burke/">LinkedIn</a>.</p>



<p><a href="https://www.linkedin.com/in/ezekiel-zeke-burke/overlay/about-this-profile/" target="_blank" rel="noreferrer noopener">Ezekiel Burke</a><em> is the founder of <a href="https://ironelephantsolutions.com/" target="_blank" rel="noreferrer noopener">Iron Elephant Solutions</a>. He focuses on building custom, scalable, and affordable software that helps businesses work smarter. With 15+ years of experience, he specializes in full-stack development, process automation and systems integration, creating solutions that simplify complex workflows.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Fuzzy Searches with SQLite&#8217;s SOUNDEX</title>
		<link>https://blog.xojo.com/2024/10/01/fuzzy-searches-with-sqlites-soundex/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 15:31:15 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[2024r3]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[Fuzzy searches]]></category>
		<category><![CDATA[SoundEx]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SQLiteDatabase]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13654</guid>

					<description><![CDATA[Though a minor update, Xojo now offers access to another core SQLite function: SOUNDEX. What is SOUNDEX? SOUNDEX is a core function in SQLite that&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Though a minor update, Xojo now offers access to another core SQLite function: SOUNDEX.</p>



<h2 class="wp-block-heading">What is SOUNDEX?</h2>



<p>SOUNDEX is a core function in SQLite that encodes a string into a 4-byte sequence, enabling indexing based on pronunciation. While the technical details of the algorithm are available on <a href="https://en.wikipedia.org/wiki/Soundex" target="_blank" rel="noreferrer noopener">Wikipedia</a>, the gist is that SOUNDEX(&#8220;Smith&#8221;) will match SOUNDEX(&#8220;Smythe&#8221;), making it useful for large searches to identify different spellings of the same term.</p>



<h2 class="wp-block-heading">How is it used?</h2>



<p>For the curious, you can see how words are indexed by simply invoking a select on a SOUNDEX term:</p>



<pre class="wp-block-code"><code>Var db As New SQLiteDatabase
db.Connect

Var rs As RowSet
rs = db.SelectSQL("SELECT SOUNDEX('Smith')")
Var smith As String = rs.ColumnAt(0).StringValue
rs = db.SelectSQL("SELECT SOUNDEX('Smythe')")
Var smythe As String = rs.ColumnAt(0).StringValue</code></pre>



<p>Running this you&#8217;ll notice that &#8216;Smith&#8217; and &#8216;Smythe&#8217; both return the same SOUNDEX 4-byte sequence of &#8220;S530&#8221; &#8212; Here&#8217;s a quick breakdown of how this was generated:</p>



<ol class="wp-block-list">
<li><strong>First Letter (S)</strong>: The first letter of the name stays the same, so &#8220;S&#8221; from the name &#8220;Smith&#8221; or &#8220;Smythe&#8221; becomes the first character in the code.</li>



<li><strong>Numbers (530)</strong>: The remaining characters in the code represent the sounds of the next letters in the name. Each number is based on a group of similar-sounding consonants:
<ul class="wp-block-list">
<li><strong>5</strong>&nbsp;= &#8220;M&#8221; (because M sounds like &#8220;M&#8221; in &#8220;Smith&#8221; or &#8220;Smythe&#8221;)</li>



<li><strong>3</strong>&nbsp;= &#8220;T&#8221; (because T sounds like &#8220;T&#8221; in &#8220;Smith&#8221; or &#8220;Smythe&#8221;)</li>



<li><strong>0</strong>&nbsp;= No sound match or a vowel, so it acts as a filler to complete the 4-character code.</li>
</ul>
</li>
</ol>



<h2 class="wp-block-heading">Practical Use Case</h2>



<p>With a better understanding of the algorithm, we can put it to practical use by searching our database for names that sound similar to &#8220;Smith.&#8221;</p>



<pre class="wp-block-code"><code>db.ExecuteSQL("CREATE TABLE contacts(id INTEGER PRIMARY KEY, name TEXT)")
db.ExecuteSQL("INSERT INTO contacts (name) VALUES ('Smith'), ('Smythe'), ('Simith'), ('John')")

rs = db.SelectSQL("SELECT name FROM contacts WHERE SOUNDEX(name) = SOUNDEX('Smith')")

// Expected to find 3 names: Smith, Smythe, and Simith
Var namesFound As Integer = rs.RowCount</code></pre>



<h2 class="wp-block-heading">The Fuzzy Conclusion</h2>



<p>Because the SOUNDEX algorithm is designed around English pronunciation patterns, it may not work as well for languages with different sound structures or alphabets, so results may vary depending on the language. It&#8217;s also worth noting that this feature is available for all targets, except Android at this time.</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo 2024r3 is Now Available!</title>
		<link>https://blog.xojo.com/2024/10/01/xojo-2024r3-is-now-available/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 15:29:54 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[2024r3]]></category>
		<category><![CDATA[Code Editor]]></category>
		<category><![CDATA[Preemptive Threads]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13757</guid>

					<description><![CDATA[We are excited to announce the arrival of Xojo 2024 Release 3, a major update to the Xojo development platform. This latest version includes over&#8230;]]></description>
										<content:encoded><![CDATA[
<p>We are excited to announce the arrival of Xojo 2024 Release 3, a major update to the Xojo development platform. This latest version includes over 200 changes and improvements, enhancing the overall user experience and expanding the platform&#8217;s capabilities.</p>



<h2 class="wp-block-heading">What&#8217;s New in Xojo 2024 Release 3</h2>



<p>We&#8217;ve been working hard to bring you the best possible cross-platform development experience, and Xojo 2024 Release 3 delivers. Here are some of the highlights:</p>



<div class="wp-block-columns are-vertically-aligned-top is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow">
<p class="has-text-align-center"><strong>Preemptive Threading</strong></p>



<p class="has-text-align-center">In this highly anticipated feature, take your applications to the next level with preemptive threading. Preemptive threads allow you to create more responsive and efficient code, maximizing the potential of your multi-core systems.</p>



<p class="has-text-align-center"><a href="https://blog.xojo.com/tag/preemptive-threads/" data-type="link" data-id="https://blog.xojo.com/2024/10/01/cooperative-to-preemptive-weaving-new-threads-into-your-apps/" target="_blank" rel="noreferrer noopener">Learn how to take advantage of preemptive threads.</a></p>
</div>



<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow">
<p class="has-text-align-center"><strong>Improved Code Editor</strong></p>



<p class="has-text-align-center">We&#8217;ve made significant improvements to the Code Editor, including row highlighting, a command bar button for Standardize Format, and Syntax Help area size control, making it easier for you to write and maintain your code.</p>



<p class="has-text-align-center"><a href="https://blog.xojo.com/2024/10/01/xojo-code-editor-changes-line-highlight-syntax-help-area-and-standardize-format/" data-type="link" data-id="https://blog.xojo.com/2024/10/01/xojo-code-editor-changes-line-highlight-syntax-help-area-and-standardize-format/" target="_blank" rel="noreferrer noopener">Learn about the new Code Editor changes.</a></p>
</div>
</div>



<div class="wp-block-columns are-vertically-aligned-top is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow">
<p class="has-text-align-center"><strong>Web Framework Updates</strong></p>



<p class="has-text-align-center">The Web framework now uses Bootstrap v5.3.3 and Bootstrap Icons v1.11.3, and supports adding CSS classes to controls, giving you more flexibility and customization options.</p>



<p class="has-text-align-center"><a href="https://blog.xojo.com/2024/10/01/introducing-named-color-and-css-classes-in-xojo-web/" data-type="link" data-id="https://blog.xojo.com/2024/10/01/introducing-named-color-and-css-classes-in-xojo-web/" target="_blank" rel="noreferrer noopener">Read about the Web framework improvements.</a></p>
</div>



<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow">
<p class="has-text-align-center"><strong>Native Platform Enhancements</strong></p>



<p class="has-text-align-center">macOS Popovers can now be resized, and the Windows HTMLViewer can access the camera and microphone, while the iOS Picture control can access EXIF metadata.</p>



<p class="has-text-align-center"><a href="https://blog.xojo.com/2024/10/01/photos-metadata-and-location-on-ios-pictures/" target="_blank" rel="noreferrer noopener">Check out this post about the iOS picture control enhancements and more.</a></p>
</div>
</div>



<div class="wp-block-columns are-vertically-aligned-top is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow">
<p class="has-text-align-center"><strong>Android Support</strong></p>



<p class="has-text-align-center">Xojo 2024 Release 3 introduces Android tablet support, improved Declare support, and RegEx classes, making it easier for you to create Android apps.</p>



<p class="has-text-align-center"><a href="https://blog.xojo.com/2024/10/01/android-tablet-support/" data-type="link" data-id="https://blog.xojo.com/2024/10/01/android-tablet-support/" target="_blank" rel="noreferrer noopener">Android Tablet Support</a> • <a href="https://blog.xojo.com/2024/10/01/android-declare-and-library-enhancements/" data-type="link" data-id="https://blog.xojo.com/2024/10/01/android-declare-and-library-enhancements/" target="_blank" rel="noreferrer noopener">Enhanced Android Declares &amp; Library</a></p>
</div>



<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow">
<p class="has-text-align-center"><strong>Fuzzy Searches with SQLite&#8217;s SOUNDEX</strong></p>



<p class="has-text-align-center">We&#8217;ve added support for SQLite&#8217;s SOUNDEX function, which enables fuzzy searches to help you find similar-sounding words and phrases in your database.</p>



<p class="has-text-align-center"><a href="https://blog.xojo.com/2024/10/01/fuzzy-searches-with-sqlites-soundex/" data-type="link" data-id="https://blog.xojo.com/2024/10/01/fuzzy-searches-with-sqlites-soundex/" target="_blank" rel="noreferrer noopener">Read about SQLite SOUNDEX support.</a></p>
</div>
</div>



<p>These updates and enhancements are designed to make your development experience more efficient, productive, and enjoyable. Whether you&#8217;re building a new application or updating an existing one, Xojo 2024 Release 3 provides you with the tools and capabilities you need to succeed.</p>



<h2 class="wp-block-heading">Get Started</h2>



<p>To learn more about Xojo 2024 Release 3 and to get started with the development process, please visit the <a href="https://documentation.xojo.com/versions/2024r3/resources/release_notes/2024r3.html" data-type="link" data-id="https://documentation.xojo.com/versions/2024r3/resources/release_notes/2024r3.html" target="_blank" rel="noreferrer noopener">Xojo 2024r3 Release Notes</a>. The update can be downloaded right now, from the <a href="https://xojo.com/download/" data-type="link" data-id="https://xojo.com/download/" target="_blank" rel="noreferrer noopener">Xojo downloads page</a>.</p>



<h3 class="wp-block-heading">What&#8217;s Next?</h3>



<p>We&#8217;re always working on new features, updates, and enhancements to our platform. If you have any suggestions or ideas, please don&#8217;t hesitate to add them to the <a href="https://tracker.xojo.com/xojoinc/xojo" data-type="link" data-id="https://tracker.xojo.com/xojoinc/xojo" target="_blank" rel="noreferrer noopener">Xojo tracker</a>. We&#8217;re always looking for ways to improve and expand Xojo.</p>



<p class="has-text-align-center"><strong>Thank you for being part of the Xojo community. We&#8217;re excited to see what you&#8217;ll create with Xojo 2024r3!</strong></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using a WebDataSource to Display Millions of Rows in a WebListBox</title>
		<link>https://blog.xojo.com/2024/08/01/using-a-webdatasource-to-display-millions-of-rows-in-a-weblistbox/</link>
		
		<dc:creator><![CDATA[Ricardo Cruz]]></dc:creator>
		<pubDate>Thu, 01 Aug 2024 18:31:45 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SQLiteDatabase]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[WebListBox]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13373</guid>

					<description><![CDATA[If you are wondering why you would use a WebDataSource for your WebListBox, this post will give you some arguments and tips for making that decision and implementing it.]]></description>
										<content:encoded><![CDATA[
<p>If you are wondering why you would use a WebDataSource for your WebListBox, this post gives you some arguments and tips for making that decision and implementing it.</p>



<h2 class="wp-block-heading">Why would you need a WebDataSource, isn’t AddRow enough?</h2>



<p>If you are making a quick prototype, or for small data sets that won&#8217;t grow too much, yes, you can absolutely place a WebListBox into your WebPage and fill it using AddRow. If your WebListBox displays a fixed, small amount of data, say around 500~1000 rows, WebDataSource can be overkill.<br><br>However, for data that comes from a large database, it&#8217;s a different story. You could waste precious server resources duplicating the same data you have in your database into your app’s memory. And even worse, the data would be duplicated in every Session seeing that WebListBox.<br><br>In this tutorial, this is the WebListBox we are going to build:</p>



<figure class="wp-block-video"><video height="1416" style="aspect-ratio: 1368 / 1416;" width="1368" controls src="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-14.42.03.mp4.mp4"></video></figure>



<h2 class="wp-block-heading">Let’s prepare a million records database to play with.</h2>



<p>In this example we will use a humble SQLite database, but keep in mind a WebDataSource can be anything. For example you could display the result of calling an external API, or your hard drive filesystem.</p>



<p>The following SQL creates a table called “things”, with three columns: “foo”, “bar” and “baz” with one million rows:</p>



<pre class="wp-block-code"><code>CREATE TABLE things (
  id    INTEGER PRIMARY KEY AUTOINCREMENT,
  foo TEXT,
  bar TEXT,
  baz TEXT
);

-- Time to populate that table
WITH RECURSIVE cnt(x) AS 
(
   SELECT
      1 
   UNION ALL
   SELECT
      x + 1 
   FROM
      cnt LIMIT 1000000
)
INSERT INTO things (foo, bar, baz)
SELECT
    'foo_' || x AS foo,
    'bar_' || x  AS bar,
    'baz_' || x AS baz
FROM cnt;

-- Finally, let's create some indexes, so we can sort the columns quickly
CREATE INDEX "idx_foo" ON things (
    foo, id, bar, baz
);

CREATE INDEX "idx_bar" ON things (
    bar, id, foo, baz
);

CREATE INDEX "idx_baz" ON things (
    baz, id, foo, bar
);

VACUUM;</code></pre>



<p>We just need to store this SQL as a string constant, for convenience. Let’s create one, called <code>kDatabaseSetupSQLite</code> in your Application class, and paste it above the SQL code.</p>



<h2 class="wp-block-heading">First Time Setup</h2>



<p>The first time we launch the application, we need to make sure our database file has been created and populated. It won&#8217;t take too much to generate the database, but we&#8217;ll try to do it just once anyway.</p>



<p>Create a new method in your App class, called DBFile, that returns a FolderItem, pointing to the place we want to store the DataBase. Make it Public, as we will use this method later from the Session. The contents:</p>



<pre class="wp-block-code"><code>Return SpecialFolder.Desktop.Child("test-db.sqlite")</code></pre>



<p>Nothing fancy. Use another path if you want. It will be around ~200MB, just remember to delete it when you don&#8217;t need it anymore.</p>



<p>Let&#8217;s create another App method, called SetupDatabase. It will be in charge of creating and populating the database just once, so if you restart the server, the data will still be there:</p>



<pre class="wp-block-code"><code>Var db As New SQLiteDatabase
db.DatabaseFile = DBFile
db.WriteAheadLogging = True

// The file is already there, no need to build it again
If db.DatabaseFile.Exists Then
  Return
End If

db.CreateDatabase
db.Connect
db.ExecuteSQL(kDatabaseSetupSQLite)</code></pre>



<p>Lastly, implement the App.Opening event and add a method call to SetupDatabase:</p>



<pre class="wp-block-code"><code>SetupDatabase</code></pre>



<p>That should do the trick.</p>



<h2 class="wp-block-heading">Preparing the Session</h2>



<p>It&#8217;s recommended to have a Database instance for each Session. Add a new public Property to your Session class called Database of type SQLiteDatabase.</p>



<p>Then, add a handler for the Opening event with the following code:</p>



<pre class="wp-block-code"><code>Database = New SQLiteDatabase
Database.DatabaseFile = App.DBFile
Database.WriteAheadLogging = True
Database.Connect</code></pre>



<p>Every time a user arrives to the web application, a new isolated SQLiteDatabase connection will be created.</p>



<h2 class="wp-block-heading">Implementing the WebDataSource Interface</h2>



<p>Since Xojo 2024r2, the amount of methods you need in order to implement WebDataSource has been reduced.</p>



<p>Create a new class called DatabaseDataSource. Then, in the inspector panel, select the WebDataSource interface:</p>



<figure class="wp-block-video"><video height="1528" style="aspect-ratio: 2560 / 1528;" width="2560" controls src="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-11.48.19.mp4.mp4"></video></figure>



<p>This includes the three required methods: ColumnData, RowCount and RowData.</p>



<p><strong>ColumnData</strong><br>In this method, you need to return an array of <a href="https://documentation.xojo.com/api/web/weblistboxcolumndata.html#weblistboxcolumndata">WebListBoxColumnData</a>. We have four columns in this example, here is the code:</p>



<pre class="wp-block-code"><code>Var result() As WebListBoxColumnData
result.Add(New WebListBoxColumnData("ID", "id"))
result.Add(New WebListBoxColumnData("Foo", "foo"))
result.Add(New WebListBoxColumnData("Bar", "bar"))
result.Add(New WebListBoxColumnData("Baz", "baz"))

Return result</code></pre>



<p><strong>RowCount</strong><br>Xojo needs to know the amount of data your data source has. Returning an Integer is enough, but we will query our database.</p>



<pre class="wp-block-code"><code>Try
  Var rows As RowSet = Session.Database.SelectSQL("SELECT COUNT(*) AS counter FROM things")
  Return rows.Column("counter").IntegerValue
Catch DatabaseException
  Return 0
End Try</code></pre>



<p><strong>RowData</strong><br>This is the place where you need to return the row contents. As you can see, there is a rowCount and a rowOffset parameter, meaning that we won&#8217;t need to return 1 million records. The control just loads a subset. The amount is dynamically calculated, and varies depending on the height of your WebListBox and the height of the rows.</p>



<p>A sortColumns parameter is also provided. If you allow your users to sort the columns, you need to use it to know the column and direction. Fortunately, this example has sortable columns. Here is the code to comply with the WebDataSource Interface:</p>



<pre class="wp-block-code"><code>Var sql As String = "SELECT id, foo, bar, baz FROM things"
If sortColumns &lt;&gt; "" Then
  sql = sql + " ORDER BY " + sortColumns
End If
sql = sql + " LIMIT " + rowOffset.ToString + ", " + rowCount.ToString

Var result() As WebListBoxRowData
Var rows As RowSet = Session.Database.SelectSQL(sql)

// This isn't needed, it's just to demonstrate how to use cell renderers
Var style As New WebStyle
style.Bold = True
style.BackgroundColor = Color.Teal
style.ForegroundColor = Color.White

For Each row As DatabaseRow In rows
  Var newRowData As New WebListBoxRowData
  newRowData.PrimaryKey = row.Column("id").IntegerValue
  newRowData.Value("id") = row.Column("id")
  newRowData.Value("foo") = row.Column("foo")
  newRowData.Value("bar") = New WebListBoxStyleRenderer(style, row.Column("bar"))
  newRowData.Value("baz") = row.Column("baz")
  result.Add(newRowData)
Next

Return result</code></pre>



<h2 class="wp-block-heading">Preparing the User Interface</h2>



<p>You&#8217;ve reached the easiest part, building the interface takes less than a minute.</p>



<ol class="wp-block-list">
<li>Drop a DatabaseDataSource control into your WebPage</li>



<li>Drop a WebListBox control into your WebPage</li>



<li>In the WebListBox Opening event, configure the DataSource</li>
</ol>



<p>If you name your DataSource instance &#8220;MyDataSource&#8221;, this is the line of code required in the WebListBox Opening event:</p>



<pre class="wp-block-code"><code>Me.DataSource = MyDataSource</code></pre>



<p>Here is a short video:</p>



<figure class="wp-block-video"><video height="1682" style="aspect-ratio: 2800 / 1682;" width="2800" controls src="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-12.21.41.mp4.mp4"></video></figure>



<h2 class="wp-block-heading">That&#8217;s It!</h2>



<p>The WebListBox control, when combined with a WebDataSource, is a very robust and performant solution for displaying a large set of data.</p>



<p>Download the project:</p>



<div class="wp-block-file"><a id="wp-block-file--media-6f1fe487-dbb0-4d6e-a5c9-3a89f0f2fb9b" href="https://blog.xojo.com/wp-content/uploads/2024/07/weblistbox-million-rows.xojo_binary_project-1.zip">weblistbox-million-rows.xojo_binary_project</a></div>



<p>Happy coding!</p>



<p><em>Ricardo has always been curious about how things work. Growing up surrounded by computers</em> he became interested in <em>web technologies in the dial-up connections era. Xojo has been his secret weapon and language of preference since 2018. When he’s not online, chances are he will be scuba diving … or crocheting amigurumis. Find Ricardo on Twitter <a href="https://web.archive.org/web/20220805000833/https://www.twitter.com/piradoiv" target="_blank" rel="noreferrer noopener">@piradoiv</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-14.42.03.mp4.mp4" length="2629948" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-11.48.19.mp4.mp4" length="1234967" type="video/mp4" />
<enclosure url="https://blog.xojo.com/wp-content/uploads/2024/07/Grabacion-de-pantalla-2024-06-18-a-las-12.21.41.mp4.mp4" length="2146506" type="video/mp4" />

			</item>
		<item>
		<title>New Database Connections</title>
		<link>https://blog.xojo.com/2024/06/26/new-database-connections/</link>
		
		<dc:creator><![CDATA[William Yu]]></dc:creator>
		<pubDate>Wed, 26 Jun 2024 15:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[2024r2]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Console]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[ODBC]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13226</guid>

					<description><![CDATA[While Xojo has always supported adding database connections, the old method was far from ideal. Let's delve into the improved approach using the new DatabaseConnection project items and explore some recent additions to our database API.]]></description>
										<content:encoded><![CDATA[
<p>While Xojo has always supported adding database connections, the old method was far from ideal. Let&#8217;s delve into the improved approach using the new Database Connection project items and explore some recent additions to our database API.</p>



<h2 class="wp-block-heading">Out With The Old</h2>



<p>The old database connections were quite limiting, requiring you to create a new connection and re-enter all the parameters whenever one changed. With our new Database Connection items, you can now easily update specific connection parameters directly in the inspector.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="303" src="https://blog.xojo.com/wp-content/uploads/2024/06/PostgresqlDBConnectionModification-1024x303.png" alt="" class="wp-image-13230" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/PostgresqlDBConnectionModification-1024x303.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/PostgresqlDBConnectionModification-300x89.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/PostgresqlDBConnectionModification-768x228.png 768w, https://blog.xojo.com/wp-content/uploads/2024/06/PostgresqlDBConnectionModification-1536x455.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/06/PostgresqlDBConnectionModification-2048x607.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>Additionally, you can now choose whether the item will auto-connect or if you prefer to connect to it later in your code.</p>



<h2 class="wp-block-heading">Connecting to a Specific Database</h2>



<p>There are times when you need to connect to a database for debugging and testing, but for the final builds, you want to connect to your production database/server. Setting this up correctly with the old database connection method required creating two separate connection items—one for debug and one for release. With the new Database Connection items, this process is much simpler and fits more easily into the build process.  You now have several new Database Connection subitems that can be customized based on the stage of your build. These subitems are linked to the Stage Code in your Shared Build Settings, ensuring that when you build a final release, your database connection uses the correct settings automatically.</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="329" src="https://blog.xojo.com/wp-content/uploads/2024/06/DatabaseConnectionStageCode-1024x329.png" alt="" class="wp-image-13238" srcset="https://blog.xojo.com/wp-content/uploads/2024/06/DatabaseConnectionStageCode-1024x329.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/06/DatabaseConnectionStageCode-300x96.png 300w, https://blog.xojo.com/wp-content/uploads/2024/06/DatabaseConnectionStageCode-768x247.png 768w, https://blog.xojo.com/wp-content/uploads/2024/06/DatabaseConnectionStageCode-1536x493.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/06/DatabaseConnectionStageCode.png 1968w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Additional Database Features</h2>



<p>In addition to this change, there are two new database APIs that may be useful to you:</p>



<ol class="wp-block-list">
<li>A new method, IsConnected, has been added to the SQLiteDatabase, ODBCDatabase, PostgreSQLDatabase, and MySQLCommunityServer classes. This method returns true if the connection is still active, and false if it is not.</li>



<li>We&#8217;ve enhanced <a href="https://documentation.xojo.com/api/databases/database.html#database-addrow">Database.AddRow</a> with a new signature that returns the unique ID of the newly inserted row. This feature is supported for SQLiteDatabase, ODBCDatabase, PostgreSQLDatabase, and MySQLCommunityServer classes. It is recommended to use this new API instead of the deprecated SQLiteDatabase.LastRowID and MySQLCommunityServer.LastInsertedRowID</li>
</ol>



<p>Let&#8217;s explore how the new Database.AddRow feature can assist you. Previously, only SQLiteDatabase and MySQLCommunityServer had APIs to retrieve the unique ID of the last inserted row. Now, PostgreSQLDatabase and ODBCDatabase also have this capability by using the new <code>Database.AddRow(tableName As String, row As DatabaseRow, idColumnName As String = "") As Integer</code></p>



<p>The new aspect of this signature is the idColumnName parameter and the return value. For databases that support the SQL <strong>RETURNING</strong> clause, the idColumnName specifies the column whose value will be returned.  For databases that do not support the <strong>RETURNING</strong> clause, we will use the suitable method for each specific database to return a unique value.</p>



<p>We recognize the significance of databases in your Xojo apps. So with these updates to database connectivity for your desktop, web and console apps, and the addition of new features, we aim to make your database programming easier and more efficient.</p>



<p><em><em><em>William Yu grew up in Canada learning to program BASIC on a Vic-20. He is Xojo’s resident Windows and Linux engineer, among his many other skills. Some may say he has joined the dark side here in the USA, but he will always be a Canadian at heart.</em></em></em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The Power of Transactions in SQLite with Xojo</title>
		<link>https://blog.xojo.com/2024/06/12/the-power-of-transactions-in-sqlite-with-xojo/</link>
		
		<dc:creator><![CDATA[Martin T.]]></dc:creator>
		<pubDate>Wed, 12 Jun 2024 16:06:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=13056</guid>

					<description><![CDATA[SQLite is a powerful, serverless database engine widely used in various applications. Transactions in SQLite play a crucial role in ensuring data integrity and consistency.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>SQLite is a powerful, serverless database engine widely used in various applications. Transactions in SQLite play a crucial role in ensuring data integrity and consistency. In Xojo, SQLiteDatabase.BeginTransaction, SQLiteDatabase.CommitTransaction, and SQLiteDatabase.RollbackTransaction provide easy ways to manage transactions.</p>



<h2 class="wp-block-heading">What are Transactions?</h2>



<p>A transaction is a sequence of SQL commands executed as a single unit, adhering to the <a href="https://en.wikipedia.org/wiki/ACID">ACID</a> properties:</p>



<ul class="wp-block-list">
<li>Atomicity: All or none of the changes are applied.</li>



<li>Consistency: The database remains in a valid state.</li>



<li>Isolation: Concurrent transactions do not interfere with each other. </li>



<li>Durability: Once committed, changes are permanent.</li>
</ul>



<h2 class="wp-block-heading">Basic Transaction Commands</h2>



<p>SQLite supports three main commands for transactions:</p>



<ul class="wp-block-list">
<li>BEGIN TRANSACTION: Starts a new transaction.</li>



<li>COMMIT: Finalizes changes and makes them permanent.</li>



<li>ROLLBACK: Reverts changes made since the last BEGIN TRANSACTION. </li>
</ul>



<h3 class="wp-block-heading">Sample in Xojo</h3>



<p>Let’s consider a banking application where money is transferred between accounts. Without transactions, inconsistencies might occur. For example, if the first update (deducting money from one account) succeeds but the second update (adding money to another account) fails, the database will be left in an inconsistent state, reflecting a transfer that didn’t fully happen. Using transactions ensures that both updates either succeed or fail together, maintaining consistency. </p>



<pre id="xojo" class="wp-block-code"><code>Var db As New SQLiteDatabase
db.DatabaseFile = FolderItem.ShowOpenFileDialog("bank.db")
If db.Connect Then
  Try
    db.BeginTransaction
    db.ExecuteSQL("UPDATE accounts SET balance=balance-100 WHERE account_number=123")
    db.ExecuteSQL("UPDATE accounts SET balance=balance+100 WHERE account_number=456")
    db.CommitTransaction
  Catch e As DatabaseException
    db.RollbackTransaction
    MessageBox("Transaction failed: " + e.Message)
  End Try
Else
  MessageBox("Failed to connect to the database")
End If</code></pre>



<p>In this example, BeginTransaction starts the transaction. The UPDATE commands perform the transfer. If successful, CommitTransaction finalizes the changes. If an error occurs, RollbackTransaction reverts all changes.</p>



<h2 class="wp-block-heading">Advanced Transaction Control</h2>



<p>SQLite also offers advanced transaction modes: DEFERRED, IMMEDIATE, and EXCLUSIVE.</p>



<ul class="wp-block-list">
<li>DEFERRED: Default mode, acquires a write lock only when the first write operation occurs.</li>



<li>IMMEDIATE: Acquires a write lock immediately upon transaction start. </li>



<li>EXCLUSIVE: Prevents all other read and write operations during the transaction.</li>
</ul>



<p>Choosing the transaction type depends on the application’s specific requirements. DEFERRED balances concurrency and consistency, while IMMEDIATE and EXCLUSIVE provide higher isolation at the cost of concurrency.</p>



<h3 class="wp-block-heading">Example of Advanced Transaction</h3>



<pre id="xojo" class="wp-block-code"><code>If db.Connect Then
  Try
    db.ExecuteSQL("BEGIN IMMEDIATE TRANSACTION")

    ' Perform read and write operations here

    db.CommitTransaction
  Catch e As DatabaseException
    db.RollbackTransaction
    MessageBox("Transaction failed: " + e.Message)
  End Try
Else
  MessageBox("Failed to connect to the database")
End If</code></pre>



<p>In this example, an IMMEDIATE transaction ensures exclusive access from the start.</p>



<h2 class="wp-block-heading">Transaction Speed Considerations</h2>



<p>The speed of transactions in SQLite can be influenced by various factors:</p>



<ul class="wp-block-list">
<li>Batching Operations: Grouping multiple operations in a single transaction can significantly improve performance.</li>



<li>Disk I/O: The underlying storage medium and its I/O performance impact transaction speed.</li>



<li>Transaction Type: IMMEDIATE and EXCLUSIVE transactions might be slower due to locking mechanisms but provide higher isolation.</li>
</ul>



<p>Batching multiple operations into a single transaction reduces the overhead of repeatedly acquiring and releasing locks, leading to faster execution.</p>



<h2 class="wp-block-heading">Benefits of Using Transactions</h2>



<p>Using transactions offers numerous benefits:</p>



<ol class="wp-block-list">
<li>Atomicity: Prevents the database from being left in an inconsistent state due to partial updates.</li>



<li>Consistency: Ensures the integrity of the database by transitioning only to valid states.</li>



<li>Isolation: Prevents interference between concurrent transactions. </li>



<li>Durability: Ensures that committed changes are permanent, even in the event of a system failure.</li>
</ol>



<p>By understanding and applying transactions, developers can create robust applications that handle data modifications seamlessly, minimizing the risk of errors and inconsistencies.</p>



<p>Based on the <a href="https://ducklet.app/blog/2024/01/17/the-power-of-transactions-in-sqlite/">Ducklet Blog</a> article. Happy coding!</p>



<p><em>Martin T. is a Xojo MVP and has been very involved in testing Android support.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQL 50th Anniversary</title>
		<link>https://blog.xojo.com/2024/04/15/sql-50th-anniversary/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Mon, 15 Apr 2024 15:19:40 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Fun]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[IBM]]></category>
		<category><![CDATA[MS SQL Server]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12874</guid>

					<description><![CDATA[SQL is 50 years old! It was first introduced in a 1974 paper titled “SEQUEL: A STRUCTURED ENGLISH QUERY LANGUAGE” by Donald Chamberlin and Raymond&#8230;]]></description>
										<content:encoded><![CDATA[
<p><a href="https://en.wikipedia.org/wiki/SQL">SQL</a> is 50 years old! It was first introduced in a 1974 paper titled “<a href="https://s3.us.cloud-object-storage.appdomain.cloud/res-files/2705-sequel-1974.pdf">SEQUEL: A STRUCTURED ENGLISH QUERY LANGUAGE</a>” by Donald Chamberlin and Raymond Boyce who were part of the IBM Research Laboratory in San Jose California.</p>



<p>This paper probably explains the biggest issue regarding SQL that persists to this day: its pronunciation.</p>



<p>I always flip between saying “sequel” and “ess cue ell” depending on context. The authors used SEQUEL as an <a href="https://www.merriam-webster.com/dictionary/acronym">acronym</a> of <strong>S</strong>tructured <strong>E</strong>nglish <strong>QUE</strong>ry <strong>L</strong>anguage. Over time this was referred to as Structured Query Language and the <a href="https://www.merriam-webster.com/dictionary/initialism">initialism</a> of SQL took hold. Still, the pronunciation of sequel seems to have also stuck. Anyway, pronounce it how you want — I won’t judge.</p>



<p>I&#8217;ve sometimes seen people claim that SQL stands for Standard Query Language. As the above clearly shows, that is not true. And if you&#8217;ve used SQL at all with more than one database, you also have empirical evidence that there is not much standard about it beyond the main keywords.</p>



<p>The <a href="https://s3.us.cloud-object-storage.appdomain.cloud/res-files/2705-sequel-1974.pdf">paper itself</a> is only about 15 pages, so not long at all. I found this surprising as I expected it to be some lengthy and detailed specification written for academics.</p>



<p>But it’s not.</p>



<p>It starts by talking about the relational model of data, a somewhat new concept at the time (first <a href="https://en.wikipedia.org/wiki/Relational_model">described in 1969</a>), and the predicate calculus, introducing a sublanguage called SQUARE, which strikes me a somewhat functional way of querying relational data. Math nerds do love their functional languages.</p>



<p>The authors then go on to introduce SEQUEL as a substitute for SQUARE and it’s here where we see the first syntax that you might recognize:</p>



<pre class="wp-block-code"><code>SELECT NAME
FROM   EMP
WHERE  DEPT = ’TOY’</code></pre>



<p>Boolean expressions in the WHERE clause are also covered along with functions in the SELECT clause. These are all things still being used to this day.</p>



<p>The main justification the authors use for SEQUEL is that the concepts of predicate calculus and SQUARE require &#8220;too much sophistication for the ordinary user&#8221;. I won’t argue with that!</p>



<p>They drive that point home by showing how to get data results using some example queries, first by using SQUARE and then comparing to the SEQUEL equivalents. Their first query is this:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Find the names of managers who manage more than ten employees.</p>
</blockquote>



<p>Note that for this example, there is a previously defined database with one of the tables as follows:</p>



<p>EMP (NAME, DEPT, MGR, SAL, COMM)</p>



<p>The SQUARE example looks like this:</p>



<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="122" src="https://blog.xojo.com/wp-content/uploads/2024/04/Pasted-Graphic-1024x122.png" alt="" class="wp-image-12878" srcset="https://blog.xojo.com/wp-content/uploads/2024/04/Pasted-Graphic-1024x122.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/04/Pasted-Graphic-300x36.png 300w, https://blog.xojo.com/wp-content/uploads/2024/04/Pasted-Graphic-768x92.png 768w, https://blog.xojo.com/wp-content/uploads/2024/04/Pasted-Graphic-1536x184.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/04/Pasted-Graphic.png 1672w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>I’m not going to even try to explain this. Read the paper if you’re curious.</p>



<p>Here&#8217;s the SEQUEL version:</p>



<pre class="wp-block-code"><code>SELECT   MGR
FROM     EMP
GROUP BY MGR
WHERE    COUNT (NAME) &gt; 10</code></pre>



<p>Well, now. That certainly makes more sense to me. I&#8217;ll bet that everyone reading this knows exactly how to parse out the SEQUEL command. It would actually work as-is in a database such as SQLite today!</p>



<p>There are other examples in the paper as well. Like I said, it’s somewhat short so you might find it to be an interesting read.</p>



<p>Happy 50th Birthday, SEQUEL (SQL)!!</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite 3.45.1</title>
		<link>https://blog.xojo.com/2024/03/26/sqlite-3-45-1/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 26 Mar 2024 15:27:31 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[2024r1]]></category>
		<category><![CDATA[Database Applications]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=12700</guid>

					<description><![CDATA[Xojo 2024 Release 1 includes an updated version of SQLite for your Desktop, Web, Console and iOS apps. We have upgraded the library from 3.39.4 (which is from 2022-09-29) to 3.45.1 (released 2024-01-30). Here are a few of the improvements.]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2024 Release 1 includes an updated version of SQLite for your Desktop, Web, Console and iOS apps. We have upgraded the library from 3.39.4 (which is from 2022-09-29) to 3.45.1 (released 2024-01-30). Here are a few of the improvements.</p>



<h2 class="wp-block-heading">Functions</h2>



<p>There are a few new SQLite functions that can now be used in your SQL statements.</p>



<p><strong>concat()</strong></p>



<p>The <a href="https://www.sqlite.org/lang_corefunc.html#concat">concat()</a> function takes an arbitrary number of string parameters and concatenates them all together. Previous versions of SQLite required you to instead use the concat operator, this is the double-pipe: ||. Concat() is a standard function on many other databases (PostgreSQL, MySQL and SQL Server) so it is nice to finally see it available on SQLite as it allow more consistent SQL code.</p>



<p>Using the Chinook sample database, this SQL concatenates the Name and Composer columns from the Track table:</p>



<pre class="wp-block-code"><code>SELECT concat(Name, ‘ by ‘, Composer) FROM Track</code></pre>



<p>Here is the output:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="652" src="https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1024x652.png" alt="" class="wp-image-12701" srcset="https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1024x652.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-300x191.png 300w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-768x489.png 768w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1536x978.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-2048x1304.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>concat_ws()</strong></p>



<p>The <a href="https://www.sqlite.org/lang_corefunc.html#concat_ws">concat_ws()</a> method is <strong>concat</strong> but <strong>w</strong>ith a <strong>s</strong>eparator. Strange naming aside, it works the same except that the first parameter is used a separator that is inserted between each string. This SQL separates the Name, Composer and Milliseconds with &#8220;&#8212;&#8220;:</p>



<pre class="wp-block-code"><code>SELECT concat_ws(‘---‘, Name, Composer, Milliseconds) FROM Track</code></pre>



<p>Here is the output:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="652" src="https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1-1024x652.png" alt="" class="wp-image-12702" srcset="https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1-1024x652.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1-300x191.png 300w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1-768x489.png 768w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1-1536x978.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-1-2048x1304.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p><strong>timediff()</strong></p>



<p>The <a href="https://www.sqlite.org/lang_datefunc.html#tmdif">timediff()</a> function calculates the elapsed time between two dates and returns the result in a human-readable format.</p>



<p>This SQL displays the time difference between Dec 12, 2023 and March 26, 2024:</p>



<pre class="wp-block-code"><code>SELECT timediff('2023-12-12','2024-03-26')</code></pre>



<p>Here is the output of 3 months and 14 days (note that it is negative because the earlier date is first in the parameter list):</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="652" src="https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-2-1024x652.png" alt="" class="wp-image-12703" srcset="https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-2-1024x652.png 1024w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-2-300x191.png 300w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-2-768x489.png 768w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-2-1536x978.png 1536w, https://blog.xojo.com/wp-content/uploads/2024/03/Pasted-Graphic-2-2048x1304.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">Other Changes</h2>



<p>Overall I didn&#8217;t notice many other other significant new features. However, many bugs have been fixed, especially around  database integrity checks and the somewhat <a href="https://blog.xojo.com/2022/12/13/sqlite-new-features-in-xojo-2022r4">new JSON support</a>.</p>



<p>You can find the full list of SQLite changes on their <a href="https://www.sqlite.org/changes.html">Release History page</a>.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Simplicity and Security, Xojo Cloud is Ideal Hosting for Xojo Web Apps</title>
		<link>https://blog.xojo.com/2023/10/30/simplicity-and-security-xojo-cloud-is-ideal-hosting-for-xojo-web-apps/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Mon, 30 Oct 2023 16:00:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[App Hosting]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Security-Enhanced Linux]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SSH]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11553</guid>

					<description><![CDATA[Xojo Cloud is the premier hosting solution for developers looking for a reliable, secure and high-performance hosting environment for Xojo web applications. Xojo Cloud is developed specifically for Xojo web applications and offers a range of benefits for you and your applications that make it worth the investment.]]></description>
										<content:encoded><![CDATA[
<p>Xojo Cloud is the premier hosting solution for developers looking for a reliable, secure and high-performance hosting environment for Xojo web applications. Xojo Cloud is developed specifically for Xojo web applications and offers a range of benefits for you and your applications that make it worth the investment.</p>



<p>Xojo Cloud is <strong>optimized for Xojo applications</strong>. It is specifically designed to provide the best possible performance and stability for Xojo web applications. We optimize Xojo Cloud for performance, so your web apps will run smoothly and seamlessly. You can even monitor server stats from within the Xojo IDE.</p>



<p>Xojo Cloud is <strong>focused on simplicity and ease of use</strong> and requires zero configuration. Designed with the Xojo developer in mind, Xojo Cloud&#8217;s Control Panel makes it easy to deploy and manage web applications. Purchase a server, open a web project in Xojo and click Deploy to upload and install to Xojo Cloud. Not just for web apps, Xojo Cloud includes Apple Push Notification server (APNs) support for your iOS apps. Set up SSL, PostrgeSQL, MySQL, SFTP and a SSH Tunnel with a click in the Xojo Cloud Control Panel (the Control Panel itself is a Xojo web app). The administration of a web server is a significant and constant task; Xojo Cloud allows you to leave that behind and focus on your projects.</p>



<figure class="wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="386" data-id="12082" src="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1024x386.png" alt="Xojo Cloud Control Panel Apps Tab" class="wp-image-12082" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1024x386.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-300x113.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-768x289.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-1536x579.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Apps-Tab-2048x772.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="384" data-id="12083" src="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1024x384.png" alt="Xojo Cloud Control Panel Options Tab" class="wp-image-12083" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1024x384.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-300x112.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-768x288.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-1536x576.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Xojo-Cloud-Control-Panel-Options-Tab-2048x768.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</figure>



<p>We take security very seriously. Xojo Cloud <strong>offers advanced security features</strong> to protect your data from cyberthreats, including a smart firewall, intrusion and hacking detection and Security-Enhanced Linux. Unlike most hosting solutions that provide little to no security, each Xojo Cloud server is built with our state-of-the-art, industrial-strength, multi-tiered security system woven into its very core.&nbsp;</p>



<p>Additional features and benefits include daily automatic backups, load balancing and support from the Xojo team. With nine global hosting locations, you are able to host your Xojo web applications close to your users, for speed and an ideal overall experience. </p>



<div class="wp-block-columns are-vertically-aligned-top is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:100%">
<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="576" src="https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1024x576.png" alt="Xojo Cloud offers 3 packages offering options on RAM, storage and vCPU starting at $49/month. " class="wp-image-12078" srcset="https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1024x576.png 1024w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-300x169.png 300w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-768x432.png 768w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading-1536x864.png 1536w, https://blog.xojo.com/wp-content/uploads/2023/09/Add-a-heading.png 1600w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>
</div>



<p>In addition to the <a href="http://xojo.com/store/#cloud">standard options</a>, Xojo Cloud servers with more RAM, storage and Virtual CPUs are available. Contact&nbsp;<a href="mailto:hello@xojo.com">customer support</a>&nbsp;for details about personalized plans.&nbsp;</p>



<p>Whether you are a seasoned Xojo developer or just getting started, Xojo Cloud provides an intuitive and user-friendly hosting solution for Xojo web applications. Today is a good day to start using Xojo Cloud, visit our <a href="https://xojo.com/cloud/">website</a> to learn more or see the Xojo <a href="https://xojo.com/store/#cloud">Store</a> to pick your package and location.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Develop Database Apps with Xojo</title>
		<link>https://blog.xojo.com/2023/09/26/develop-database-apps-with-xojo/</link>
		
		<dc:creator><![CDATA[Xojo]]></dc:creator>
		<pubDate>Tue, 26 Sep 2023 18:06:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Database Applications]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[Xojo API 2.0]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9320</guid>

					<description><![CDATA[After you have designed your interface and begun coding, your next step may be to connect to a database. This blog post tells you the databases supported by Xojo, shows you where to find code samples and examples, plus tutorials and videos that walk you through connecting, updating, querying and managing database, plus, an introduction to Xojo's new DBKit. Get the resources and knowledge you need to get your first database project off the ground today.]]></description>
										<content:encoded><![CDATA[
<p>After you have designed your interface and begun coding, your next step may be to connect to a database. This blog post tells you the databases supported by Xojo, shows you where to find code samples and examples, plus tutorials and videos that walk you through connecting, updating, querying and managing a database, plus, an introduction to Xojo&#8217;s new DBKit. Get the resources and knowledge you need to get your first database project off the ground today.</p>



<span id="more-9320"></span>



<h3 class="wp-block-heading">Database Support</h3>



<p>Xojo works with a wide variety of databases. SQLite is bundled with your Xojo license and is a great beginner database for desktop, web and mobile apps. Xojo includes direct support for SQLite, PostgreSQL and MySQL. Plus, you can use <a href="https://documentation.xojo.com/topics/databases/supported_engines/odbc.html#odbc">ODBC</a> to connect to just about anything else, such as Oracle, MS-SQL Server, Microsoft Access, Firebird or even IBM iSeries.</p>



<h3 class="wp-block-heading">Examples</h3>



<p>To help you get started, there are many examples in the Examples/Databases folder included with the Xojo <a href="https://xojo.com/download/">Download</a>, including examples that connect to each of the supported databases. You can find a <a href="https://documentation.xojo.com/resources/examples.html">breakdown of the examples</a> included in the Examples folder in the Xojo Programming Language Documentation.</p>



<p><a href="http://www.xojo.com/blog/en/assets_c/2014/07/DBExamples-429.php"></a>Additionally, you can check out the <a href="https://demos.xojo.com/#customerID">Eddie’s Electronics</a> sample app (located in Examples/Sample Applications/EddiesElectronics) to see how to share database code between Xojo desktop and Xojo web apps.</p>



<p>DBKit is an example project designed to make it easier to build desktop and web applications that are front-ends to databases. Specifically, DBKit makes it easy to connect a database table to the user interface controls on a layout. DBKit also handles a lot of the interface for you.&nbsp;You can read more about <a href="https://documentation.xojo.com/topics/databases/dbkit.html">DBKit</a> in the Xojo Documentation.</p>



<h3 class="wp-block-heading">Read: Documentation</h3>



<p>After you have reviewed the examples, the <a href="https://documentation.xojo.com/topics/databases/database_basics_for_beginners.html">Database Overview</a> in the Xojo Documentation will help with next steps. Remember, Xojo comes bundled with SQLite which is an excellent database for desktop, web and mobile apps. Read more about using <a href="https://documentation.xojo.com/topics/databases/supported_engines/sqlite/overview.html">SQLite</a> in the Xojo Documentation and check out this <a href="https://documentation.xojo.com/topics/databases/supported_engines/sqlite/sqlite_basics.html">SQLite Tutorial</a> for more detail.</p>



<h3 class="wp-block-heading">Watch: Videos</h3>



<p>The Xojo YouTube channel has hundreds of videos on all things Xojo. Here are the most recent Xojo Database videos and playlists:</p>



<ul class="wp-block-list">
<li>Video: <a href="https://youtu.be/GGyu4D0ni28">Connecting to a Database from Xojo</a></li>



<li>Video: <a href="https://youtu.be/JWja37wXz2U">Updating a Database from Xojo</a></li>



<li>Video: <a href="https://youtu.be/8ENtgkzvyS0">Querying a Database from Xojo</a></li>



<li>Video: <a href="https://youtu.be/wVHYk-4XG2o">Managing the UI when Updating a Database</a></li>



<li>Video: <a href="https://youtu.be/3Jjf1Xrnm2w">Using DBKit to easily connect databases to Xojo applications</a></li>



<li>Playlist: <a href="https://www.youtube.com/playlist?list=PLPoq910Q9jXhRoPw0_mHKdVUKPXpL9TKV">Using Databases with Xojo</a> &#8211; A growing, catch-all playlist for videos related to Xojo and databases.</li>



<li>Playlist: <a href="https://www.youtube.com/playlist?list=PLPoq910Q9jXjDBrL3KymUwnagM8d7Xbia">Xojo and SQLite</a> &#8211; SQLite comes bundled with Xojo and is a great database for beginners building desktop, web and mobile apps with Xojo.</li>
</ul>



<h3 class="wp-block-heading">Vendor Documentation</h3>



<p>Lastly, you should always refer to the vendor-specific documentation for the database you are using to learn the specifics about how that database works, including SQL syntax.</p>



<ul class="wp-block-list">
<li><a href="http://www.sqlite.org/docs.html">SQLite</a></li>



<li><a href="http://www.postgresql.org/docs/">PostgreSQL</a></li>



<li><a href="http://dev.mysql.com/doc/">MySQL</a></li>



<li><a href="http://www.oracle.com/technetwork/indexes/documentation/index.html?ssSourceSiteId=ocomen">Oracle Database</a></li>



<li><a href="http://msdn.microsoft.com/en-us/library/bb545450.aspx">Microsoft SQL Server</a></li>
</ul>



<p>Xojo simplifies the development process, reduces complexity and empowers developers to create efficient and functional database applications with relative ease. The Xojo IDE is free to use for development and testing &#8211; design, develop, run and debug your app all without a license. Purchase a license when you are ready to compile your apps, licenses start at $149. Visit the <a href="https://xojo.com/store/">Xojo Store</a> to find the license right for your project.</p>



<p>If you have questions after you have reviewed these materials, the Xojo <a href="https://forum.xojo.com">Forum</a> is an accessible and essential resource for Xojo users of all levels. You can also <a href="https://www.xojo.com/company/contact.php">contact</a> Xojo directly with your questions.</p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite 3.39.4: New Features</title>
		<link>https://blog.xojo.com/2022/12/13/sqlite-new-features-in-xojo-2022r4/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 13 Dec 2022 14:32:00 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Database Applications]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=11053</guid>

					<description><![CDATA[In Xojo 2022r4, we have updated our SQLite library to SQLite v3.39.4. I thought I'd highlight a few notable upgrades including: STRICT tables
PRAGMA table_list
RIGHT and FULL OUTER JOIN
Built-in JSON support]]></description>
										<content:encoded><![CDATA[
<p>In Xojo 2022r4, we have updated our SQLite library to SQLite v3.39.4. Previously Xojo was using 3.36.0, and since there have been <a href="https://www.sqlite.org/changes.html">quite a few SQLite updates since then</a> I thought I&#8217;d highlight a few notable features:</p>



<ul class="wp-block-list"><li>STRICT tables</li><li>PRAGMA table_list</li><li>RIGHT and FULL OUTER JOIN</li><li>Built-in JSON support</li></ul>



<p>More about each of these below.</p>



<h2 class="wp-block-heading">STRICT Tables</h2>



<p>One of SQLite&#8217;s most unusual capabilities is that it does not care about what data goes into a column. Although you could specify a type for a column, it was really more of a suggestion as other types of data could be put into the column. This behavior is different than most other relational databases and can sometimes be a source of confusion.</p>



<p>Now you can create your tables using the <a href="https://www.sqlite.org/stricttables.html">STRICT keyword</a> to force them to require column types and to force the column types to always be checked when putting data into them.</p>



<p>You are still limited to INT, INTEGER, REAL, TEXT and BLOB. That means there is still no DATE or DATETIME type like you might find in other databases. Instead use TEXT with YYYY-MM-DD format.</p>



<p>However, an ANY type was added which essentially allows you to clearly state that the column can contain anything. This allows you to have a mixture of specific types and generic types in your STRICT tables.</p>



<p>Note that the STRICT keyword goes at the end of the CREATE TABLE command:</p>



<pre class="wp-block-preformatted">CREATE TABLE Team (ID INTEGER, Name TEXT, Coach TEXT, City TEXT, PRIMARY KEY(ID)) STRICT;</pre>



<p>The <a href="https://www.sqlite.org/stricttables.html">SQLite docs</a> have more information about the new STRICT table feature.</p>



<h2 class="wp-block-heading">PRAGMA table_list</h2>



<p>With Xojo you could always get the list of tables by using the <a href="https://documentation.xojo.com/api/databases/database.html#database-tables">Database.Tables()</a> method. However if you wanted to get the list of table using SQL you had to directly query the sqlite_master table.</p>



<p>Now there is a simple PRAGMA that can do the same thing:</p>



<pre class="wp-block-code"><code>PRAGMA table_list</code></pre>



<p>It returns a list of tables and some other details about the table (which may change over time <a href="https://www.sqlite.org/pragma.html#pragma_table_list">according to the SQLite docs</a>).</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-1024x852.png" alt="" class="wp-image-11057" width="625" height="520" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-1024x852.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-300x250.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x-768x639.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.16.02@2x.png 1144w" sizes="auto, (max-width: 625px) 100vw, 625px" /></figure>



<h2 class="wp-block-heading">RIGHT and FULL OUTER JOIN</h2>



<p>Joining tables is a common task with SQL. The most common type of join is an INNER JOIN where only the rows common to both tables are included in the result. Other less common types of joins include LEFT OUTER, RIGHT OUTER and FULL OUTER (sometimes OUTER is omitted when referring to these types of joins).</p>



<p>SQLite has had support for LEFT OUTER joins for a long time, but support for RIGHT OUTER and FULL OUTER were missing. But now they are here, giving your more complicated queries better compatibly with the &#8220;big name&#8221; databases.</p>



<p>Learn more about these types of joins at <a href="https://www.w3schools.com/sql/sql_join.asp">W3 schools</a>.</p>



<h2 class="wp-block-heading">JSON Support</h2>



<p>I&#8217;ve saved the big one for last: your SQL databases can now work with JSON data within columns.</p>



<p>Here is a sample table to work with with some JSON data that is stored in the players column:</p>



<pre class="wp-block-preformatted">CREATE TABLE team(id INTEGER PRIMARY KEY, Name TEXT, players TEXT);</pre>



<pre class="wp-block-preformatted">INSERT INTO TEAM VALUES (NULL, 'Seagulls', '[ {"Name":"Bob","position":"1B"}, {"Name":"Tom","position":"2B"} ]')</pre>



<pre class="wp-block-preformatted">INSERT INTO TEAM VALUES (NULL, 'Pigeons', '[ {"Name":"Bill","position":"1B"}, {"Name":"Tim","position":"2B"} ]')</pre>



<pre class="wp-block-preformatted">INSERT INTO TEAM VALUES (NULL, 'Crows', '[ {"Name":"Betty","position":"1B"}, {"Name":"Tina","position":"2B"} ]')</pre>



<p>Let&#8217;s say you want to get the first player on each team. Without SQLite JSON support you would have to pull out the JSON column data and parse it out separately. But now you can do it with this SQL like this:</p>



<pre class="wp-block-preformatted">SELECT players -&gt; 0 FROM team</pre>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="590" height="568" src="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.54.09@2x.png" alt="" class="wp-image-11063" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.54.09@2x.png 590w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-10.54.09@2x-300x289.png 300w" sizes="auto, (max-width: 590px) 100vw, 590px" /></figure>



<p>The above SQL says: for each row fetch the first array element from the JSON data in players.</p>



<p>This is how you would list all the players on all the teams:</p>



<pre class="wp-block-preformatted">SELECT team.Name, json_each.value -&gt; 'Name' FROM team, json_each(team.players)</pre>



<p>And if you want to get the actual value without the quotes, you can use the -&gt;&gt; operator (and also rename the result):</p>



<pre class="wp-block-preformatted">SELECT team.Name, json_each.value -&gt;&gt; 'Name' As PlayerName FROM team, json_each(team.players)</pre>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="544" src="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-1024x544.png" alt="" class="wp-image-11075" srcset="https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-1024x544.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-300x159.png 300w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x-768x408.png 768w, https://blog.xojo.com/wp-content/uploads/2022/12/CleanShot-2022-12-12-at-11.40.49@2x.png 1250w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>The SQLite JSON support can do much, much more which you can read about on the <a href="https://www.sqlite.org/json1.html">SQLite JSON doc page</a>.</p>



<p><em>Paul learned to program in BASIC at age 13 and has programmed in more languages than he remembers, with Xojo being an obvious favorite. When not working on Xojo, you can find him talking about retrocomputing at <a href="https://goto10.substack.com" target="_blank" rel="noreferrer noopener">Goto 10</a> and </em>on Mastodon @lefebvre@hachyderm.io.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite 3.36.0 New Features</title>
		<link>https://blog.xojo.com/2021/11/18/sqlite-new-features/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 18 Nov 2021 14:00:00 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Database Applications]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9581</guid>

					<description><![CDATA[Xojo 2021 Release 3 includes SQLite 3.36.0, which has a few new features, such as: RETURNING on DELETE, INSERT and UPDATE commands
ALTER TABLE DROP COLUMN
EXPLAIN QUERY PLAN]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2021 Release 3 includes <a href="https://www.sqlite.org/changes.html">SQLite 3.36.0</a>, which has a few new features, such as:</p>



<ul class="wp-block-list"><li>RETURNING on DELETE, INSERT and UPDATE commands</li><li>ALTER TABLE DROP COLUMN</li><li>EXPLAIN QUERY PLAN</li></ul>



<h2 class="wp-block-heading">RETURNING Clause</h2>



<p>The <a href="https://www.google.com/search?client=safari&amp;rls=en&amp;q=sqlite+returning+clause&amp;ie=UTF-8&amp;oe=UTF-8">RETURNING clause</a> can be used on DELETE, INSERT and UPDATE commands to get a value back after the command has run without having to do a separate query.</p>



<p>For example, you could send an UPDATE command that recalculates a value and have it return the new value like this:</p>



<pre class="wp-block-preformatted">UPDATE sales SET amount = amount * 2 WHERE ID = 1 RETURNING amount</pre>



<p>This would now return the newly calculated amount, where as you would previously have to issue a separate SELECT statement to get the amount.</p>



<p>This example would append &#8221; the Great&#8221; to the end of all names in the Artist table and return the new name along with the ID:</p>



<pre class="wp-block-preformatted">UPDATE Artist SET Name = Name || + " the Great" RETURNING Name, ArtistId</pre>



<p>To access the RETURNING value from Xojo, you&#8217;ll want to send the command using <a href="https://documentation.xojo.com/api/databases/database.html#database-selectsql">SelectSQL</a> instead of <a href="https://documentation.xojo.com/api/databases/database.html#database-executesql">ExecuteSQL</a> so that you can use a <a href="https://documentation.xojo.com/api/databases/rowset.html">RowSet</a> to get the values.</p>



<h2 class="wp-block-heading">DROP Column</h2>



<p>SQLite has historically been pretty inflexible when it comes to modify a table&#8217;s structure after it has been created. Until recently you could only rename a table and add new columns to it. Back in <a href="https://blog.xojo.com/2018/12/18/sqlite-3-25-adds-window-functions-and-improves-alter-table/">SQLite 3.25</a>, the ability to rename existing columns on a table was added. And now you can also <a href="https://www.sqlite.org/lang_altertable.html">remove (drop) columns</a> from a table.</p>



<p>You can do this using the standard syntax like this:</p>



<pre class="wp-block-preformatted">ALTER TABLE MyTable DROP COLUMN OldColumn;</pre>



<h2 class="wp-block-heading">Query Plan</h2>



<p>A query plan describes how SQLite processes your SQL query. It is really only useful for debugging purposes. If you have a slow-running query it can sometimes be useful to look at the query plan to see if it is pointing out an obvious problem with the query, which might be that the query is doing a table scan rather than using an index.</p>



<p>To see a query plan, you put <a href="https://www.sqlite.org/eqp.html">EXPLAIN QUERY PLAN</a> in front of the SQL query. This features has been in SQLite for a long time, but it has recently gotten some output improvements that might make it easier to use. Be sure to give it a try.</p>



<p>As an example, here is how to get the query plan for a simple query using the AlbumArtist view in the Chinook database:</p>



<p>EXPLAIN QUERY PLAN SELECT * FROM AlbumArtist</p>



<p>The query plan looks like this, with separate rows returned for each evaluation:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="662" height="282" src="https://blog.xojo.com/wp-content/uploads/2021/11/CleanShot-2021-11-10-at-10.05.51.png" alt="" class="wp-image-9585" srcset="https://blog.xojo.com/wp-content/uploads/2021/11/CleanShot-2021-11-10-at-10.05.51.png 662w, https://blog.xojo.com/wp-content/uploads/2021/11/CleanShot-2021-11-10-at-10.05.51-300x128.png 300w" sizes="auto, (max-width: 662px) 100vw, 662px" /></figure>



<p>To learn more about using SQLite with Xojo, check out these additional resources: Xojo SQLite Database <a href="https://documentation.xojo.com/api/databases/sqlitedatabase.html">Documentation</a>, <a href="https://documentation.xojo.com/topics/databases/supported_engines/sqlite/sqlite_basics.html">Tutorial</a>: SQLite Basics, <a href="https://blog.xojo.com/2021/10/28/3-steps-to-seamlessly-deploy-sqlite-projects-on-desktop-web-ios-2/">Blog Post</a>: 3 Steps to Seamlessly Deploy SQLite Projects on Desktop, Web &amp; iOS and <a href="https://blog.xojo.com/2021/03/09/backwards-sqlite-backups/">Blog Post</a>: Backwards SQLite Backups.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>3 Steps to Seamlessly Deploy SQLite Projects on Desktop, Web &#038; iOS</title>
		<link>https://blog.xojo.com/2021/10/28/3-steps-to-seamlessly-deploy-sqlite-projects-on-desktop-web-ios-2/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Thu, 28 Oct 2021 15:21:56 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Database Applications]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9363</guid>

					<description><![CDATA[This tutorial will show you how to deploy your SQLite based projects so they behave right on Desktop, Web and iOS, copying the database file to the right place on every target.]]></description>
										<content:encoded><![CDATA[
<p>This tutorial will show you how to deploy SQLite based projects on Desktop, Web and iOS, copying the SQLite database file to the right place on every target.</p>



<h2 class="wp-block-heading">1. Adding the Database File</h2>



<p>You probably created your SQLite database file using an external editor; so first add that file to your Xojo project. You can do that in several ways, but usually it&#8217;s best to add a Build Step. This way, the file will be automatically added to the folder every time you compile your app. <em>Bonus: Doing this allows you to decide to use different paths when debugging or deploying your app.</em></p>



<p>Adding a Build Step in Xojo is the same for <strong>Desktop</strong> and <strong>Web</strong> projects. Select the target in the Build Settings then&nbsp;from the contextual menu choose the &#8220;Add to Build Settings &gt; Build Step &gt; Copy Files&#8221; option.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="297" src="https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileDesktop-1024x297.png" alt="" class="wp-image-9364" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileDesktop-1024x297.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileDesktop-300x87.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileDesktop-768x222.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileDesktop.png 1084w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>This gives you access to the Inspector Panel for the just-added item where you can enter a name for the Build Step, choose if the copy file action will be executed both for debugging or deployment and, most importantly, choose the location where the file should be copied when the app compiles.</p>



<p>The Destination menu contains a number of typical paths (or most relevant folders). For example, a good destination option would be &#8220;Resources Folder&#8221;. Don&#8217;t forget to add the database file itself using the buttons on the Build Editor toolbar.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="662" height="432" src="https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileInspector.png" alt="" class="wp-image-9365" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileInspector.png 662w, https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileInspector-300x196.png 300w" sizes="auto, (max-width: 662px) 100vw, 662px" /></figure>
</div>


<p>On <strong>iOS</strong>, adding a Build Step is nearly the same as for Desktop and Web. The only difference is that you have to choose the icon with an iPhone picture in it in order to access the Build Step contextual menu&gt; In addition to that, every added resource needs to be signed with a certificate.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="1024" height="253" src="https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileiOS-1024x253.png" alt="" class="wp-image-9366" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileiOS-1024x253.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileiOS-300x74.png 300w, https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileiOS-768x190.png 768w, https://blog.xojo.com/wp-content/uploads/2021/09/CopyFileiOS.png 1124w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<h2 class="wp-block-heading">2. Copying the Database File to a &#8220;Working&#8221; Folder</h2>



<p>You may think that adding a Build Step is all you need to do, because if the database file is already copied to a well known path then you only need to provide that path as the DatabaseFile property on a new SQLiteDatabase instance. But this is not the case.</p>



<p>They are many reasons you shouldn&#8217;t do that, notably because the database would be open in read/write mode and if you write to that database file inside an application bundle, then you&#8217;d be modifying a resource and that would invalidate any certificate signature on your app.</p>



<p>The best thing to do is to check every time you run the app to see if the database file has already been copied from the app bundle (or folder) into a target folder that doesn&#8217;t have an access problem when it is time to use the database. The Application Support folder is a good place for <strong>Desktop</strong> apps, while the Documents folder is fine for <strong>Web</strong> and <strong>iOS</strong> apps.</p>



<p>For example, if our database file is named &#8220;EddiesElectronics.sqlite&#8221; and our app name is &#8220;Xojotest&#8221;, then we can add the following code fragment into the Opening Event Handler of a <strong>Desktop</strong> app. Also, make sure to add the pDatabase property to the App object in the Navigator:</p>



<pre class="wp-block-code"><code>Var source As FolderItem = SpecialFolder.Resource("EddiesElectronics.sqlite")
Var name As String = app.ExecutableFile.name.NthField(".", 1)

// Check if there is a folder with the App name in special Application Data
// if not, create it and copy the database file from Resources bundle/directory
If Not (SpecialFolder.ApplicationData.Child(name).Exists And SpecialFolder.ApplicationData.Child(name).IsFolder) Then SpecialFolder.ApplicationData.Child(name).CreateFolder

If Not SpecialFolder.ApplicationData.child(name).child(source.name).exists Then source.CopyTo(SpecialFolder.ApplicationData.Child(name))

Try
  // Create a SQLiteDatabase instance and try to open our database file from
  // the path
  pDatabase = New SQLiteDatabase
  pDatabase.DatabaseFile = SpecialFolder.ApplicationData.Child(name).Child("EddiesElectronics.sqlite")
  pDatabase.Connect

Catch e As DatabaseException
  MessageBox(e.Message)
End Try</code></pre>



<p>For an <strong>iOS</strong> app, the code would be:</p>



<pre class="wp-block-code"><code>Var source As FolderItem = SpecialFolder.Resource("EddiesElectronics.sqlite")
// Check if our database file already copied on the Documents Sandbox folder
// if not, copy the database file from Resources bundle/directory

If Not SpecialFolder.Documents.Child("EddiesElectronics.sqlite").Exists Then
  source.CopyTo(SpecialFolder.documents)
End If

Try
  // Create a SQLiteDatabase instance and try to open database file from
  // the path
  pDatabase = New SQLiteDatabase
  Var f As FolderItem = SpecialFolder.Documents
  pDatabase.DatabaseFile = f.Child("EddiesElectronics.sqlite")
  Call pDatabase.Connect
  
Catch e As RuntimeException
  MessageBox(e.Message)
End Try</code></pre>



<p>If you&#8217;re working on <strong>Xojo Cloud</strong>, the code is even shorter. First, make sure that the Copy File Build Step has the following values in the Inspector Panel:</p>



<ul class="wp-block-list">
<li><strong>Destination:</strong> Contents Folder</li>



<li><strong>Subdirectory:</strong> Documents</li>
</ul>



<p>Then, the code will be:</p>



<pre class="wp-block-code"><code>Try
  pDatabase = New SQLiteDatabase
  pDatabase.DatabaseFile = SpecialFolder.Documents.Child("EddiesElectronics.sqlite")
  pDatabase.Connect
Catch e As RuntimeException
  MessageBox(e.Message)
End Try</code></pre>



<p>What about a <strong>Web</strong> app that you host? That would mean you are in control of the folder/directory you want to use to store the app resources. Thus, it wouldn&#8217;t make much sense to automate this process (but it is certainly doable following the same principles).</p>



<h2 class="wp-block-heading">3. Simplifying the Process</h2>



<p>What we have just done works, but it means you need to change the database file name, probably for every app you build. It also means that you&#8217;ll be writing the same code snippet again and again in every new app. Wouldn&#8217;t it be great to be able to extend the SQLiteDatabase in order to simplify that?</p>



<p>Well, let&#8217;s do that! Start by adding a new Module to the example project (for example, one named &#8220;DatabaseExtensions&#8221;) with a couple of methods on it.&nbsp;The first method will be the one executed on our Desktop, Web and Console apps, because all of these targets use the SQLiteDatabase class.</p>



<p>Add a new method using the following signature in the just-created Module:</p>



<pre class="wp-block-code"><code>OpenDatabase(databaseName As String)</code></pre>



<p>It extends the SQLiteDatabase class, adding a new method that takes as parameter the name of the file we want to copy on the &#8220;work&#8221; folder/directory.</p>



<p>The code you should type on this method is:</p>



<pre class="wp-block-code"><code>pDatabase = New SQLiteDatabase

#If TargetDesktop Or TargetConsole Or TargetWeb Then

  Var source As FolderItem = SpecialFolder.Resource(databaseName)
  Var name As String = app.ExecutableFile.name.NthField(".", 1)
  // Check if there is a folder with the App name in special Application Data
  // if not, create it and copy the database file from Resources bundle/directory
  If Not (SpecialFolder.ApplicationData.Child(name).Exists And SpecialFolder.ApplicationData.Child(name).IsFolder) Then
SpecialFolder.ApplicationData.Child(name).CreateFolder
If Not SpecialFolder.ApplicationData.Child(nam).Child(Source.name).Exists Then source.CopyTo(SpecialFolder.ApplicationData.Child(name))

  Try
    // Create a SQLiteDatabase instance and try to open database file from
    // the path
    pDatabase.DatabaseFile = SpecialFolder.ApplicationData.Child(name).Child(databaseName)
    pDatabase.Connect

  Catch e As DatabaseException
    MessageBox(e.Message)
  End Try

#ElseIf TargetXojoCloud
  Try
    pDatabase.DatabaseFile = SpecialFolder.Documents.Child(databaseName)
    pDatabase.Connect
  Catch e As RuntimeException
    MessageBox(e.Message)
  End Try
#EndIf</code></pre>



<p>Of course, we need to add the &#8220;pDatabase&#8221; property to our Module too: pDatabase As SQLiteDatabase</p>



<p>Now, you&#8217;ll only need to use:</p>



<pre class="wp-block-code"><code>OpenDatabase("EddiesElectronics.sqlite")</code></pre>



<p>With the method selected in the Project Browser, click on the Attributes section of the Inspector Panel (the Cog Wheel icon), and uncheck the &#8220;iOS 64&#8221; checkbox. This way, that method will not be included when compiling for iOS apps.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="664" height="886" src="https://blog.xojo.com/wp-content/uploads/2021/09/MethodAttributes.png" alt="" class="wp-image-9367" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/MethodAttributes.png 664w, https://blog.xojo.com/wp-content/uploads/2021/09/MethodAttributes-225x300.png 225w" sizes="auto, (max-width: 664px) 100vw, 664px" /></figure>
</div>


<p>The second method is the one we will be using for iOS apps. The method signature would be:</p>



<pre class="wp-block-code"><code>OpenDatabase(databaseName As String)</code></pre>



<p>Type the following fragment of code in the associated Code Editor:</p>



<pre class="wp-block-code"><code>pDatabase = New SQLiteDatabase

Var source As FolderItem = SpecialFolder.Resource(databaseName)

// Check if the database file is already copied on the Documents Sandbox folder
// if not, copy the database file from Resources bundle/directory

If Not SpecialFolder.Documents.Child(databaseName).Exists Then
  source.CopyTo(SpecialFolder.Documents)
End If

Try
  // Create a SQLiteDatabase instance and try to open database file from
  // the path
  
  Var f As FolderItem = SpecialFolder.Documents 
  pDatabase.DatabaseFile = f.Child(databaseName)
  pDatabase.Connect
  
Catch e As RuntimeException
  MessageBox(e.Message)
End Try</code></pre>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img loading="lazy" decoding="async" width="658" height="892" src="https://blog.xojo.com/wp-content/uploads/2021/09/MethodAttributesiOS.png" alt="" class="wp-image-9368" srcset="https://blog.xojo.com/wp-content/uploads/2021/09/MethodAttributesiOS.png 658w, https://blog.xojo.com/wp-content/uploads/2021/09/MethodAttributesiOS-221x300.png 221w" sizes="auto, (max-width: 658px) 100vw, 658px" /></figure>
</div>


<p>Lastly, and with the method item still selected in the Navigator, go to the Attributes section of the Inspector Panel and make sure that the &#8220;iOS 64&#8221; checkbox is the only one selected under the &#8220;Include In&#8221; section. This way, we make sure that the method will be compiled only on iOS targets.</p>



<h2 class="wp-block-heading">To Summarize</h2>



<p>The use of Modules in combination with OOP Class Extension is a good way to get more flexibility when developing your apps, no matter if you are working on Desktop, Web or iOS. And that leads to convenient reutilization of code and less code to maintain through all your projects!</p>



<p>(You can find this article in Spanish <a href="https://www.aprendexojo.com/2021/11/tutorial-3-pasos-para-desplegar-proyectos-sqlite-en-desktop-web-y-ios/">here</a>)</p>



<p><em>Javier Menendez is an engineer at Xojo and has been using Xojo since 1998. He lives in Castellón</em>, <em>Spain and hosts regular Xojo hangouts en español. Ask Javier questions on Twitter at <a href="https://twitter.com/xojoes" target="_blank" rel="noreferrer noopener">@XojoES</a> or on the <a href="https://forum.xojo.com/u/javier_menendez/summary" target="_blank" rel="noreferrer noopener">Xojo Forum</a>.</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite 3.34.1 New Features</title>
		<link>https://blog.xojo.com/2021/03/31/sqlite-3-34-1-new-features/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Wed, 31 Mar 2021 12:03:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[WAL]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8292</guid>

					<description><![CDATA[Xojo 2021 Release 1 updates its SQLite engine to 3.34.1 (from 3.33.0). This release does not have a lot of new features, but there are&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2021 Release 1 updates its SQLite engine to 3.34.1 (from 3.33.0). This release does not have a lot of new features, but there are a few notable ones that you might find useful.</p>



<p>First, the performance of <a href="https://documentation.xojo.com/api/databases/sqlitedatabase.html#sqlitedatabase-writeaheadlogging">WAL mode</a> (write-ahead logging) is improved when there are lots of connections all accessing the same database file. This ought to provide noticeable improvements for web apps that use SQLite databases.</p>



<p>If you use <a href="https://documentation.xojo.com/topics/databases/supported_engines/sqlite/full_text_searching.html">full text searching with FTS5</a>, you can now enable <a href="https://www.sqlite.org/draft/fts5.html#trigramidx">trigram indexing</a> to allow search terms to better match within text blocks.</p>



<p>A minor change is that the &#8220;<a href="https://www.sqlite.org/draft/lang_corefunc.html#substr">substr()</a>&#8221; SQL function can now also be called &#8220;substring()&#8221; for compatibility with SQL Server.</p>



<p>There are a few other performance improvements as well. Visit the SQLite site to read the <a href="https://www.sqlite.org/draft/changes.html">official release notes</a>.</p>



<p><a href="https://blog.xojo.com/tag/sqlite/">Find more SQLite tips</a> </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Backwards SQLite Backups</title>
		<link>https://blog.xojo.com/2021/03/09/backwards-sqlite-backups/</link>
		
		<dc:creator><![CDATA[Greg O'Lone]]></dc:creator>
		<pubDate>Tue, 09 Mar 2021 16:54:16 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Backups]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8121</guid>

					<description><![CDATA[If you use SQLite databases in your apps you may or may not be aware of the Backup method which allows you to quickly and asynchronously create a backup of an existing connected database. This is especially great if you have an in-memory database and you want to store that data on disk for later reference. ]]></description>
										<content:encoded><![CDATA[
<p>If you use SQLite databases in your apps you may or may not be aware of the Backup method which allows you to quickly and asynchronously create a backup of an existing connected database. This is especially great if you have an in-memory database and you want to store that data on disk for later reference. I am using the simpler synchronous calls for this example:</p>



<p><code>memoryDB.Backup(fileDB, Nil, -1)&nbsp;</code></p>



<p>Something that&#8217;s often overlooked is that you can use the Backup method to go the other way&#8230; that is, it can be used to load a disk-based database <em>back into memory</em> by simply swapping the parameters:</p>



<pre class="wp-block-preformatted">// Connect to the database file on disk
Var fileDB as New SQLiteDatabase
fileDB.DatabaseFile = SpecialFolder.Resources.Child("template.db")
fileDB.Connect

// Create the database in memory
Var memoryDB as New SQLiteDatabase
memoryDB.Connect

// "Backup" the file database into memory
fileDB.Backup(memoryDB, Nil, -1)

// Close the file database
fileDB.Close</pre>



<p>And voila! You&#8217;ve restored the database back into memory!</p>



<p>For more information about this command, please see <a rel="noreferrer noopener" href="https://documentation.xojo.com/api/databases/sqlitedatabase.html#sqlitedatabase-backup" target="_blank">SQLiteDatabase.Backup on https://documentation.xojo.com</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Quick Tips: Xojo Cloud and Databases</title>
		<link>https://blog.xojo.com/2020/09/02/quick-tips-xojo-cloud-and-databases/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Wed, 02 Sep 2020 10:00:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7209</guid>

					<description><![CDATA[Based on recent conversations with a couple Xojo users, here are a few quick tip for uploading and working with SQLite and MySQL databases on Xojo Cloud.]]></description>
										<content:encoded><![CDATA[<p>Based on recent conversations with a couple Xojo users, here are a few quick tips for uploading and working with SQLite and MySQL databases on Xojo Cloud.</p>
<p>If you aren&#8217;t already familiar with <a href="https://www.xojo.com/cloud/">Xojo Cloud</a>, it&#8217;s simple, secure, maintenance-free hosting for your Xojo web apps. </p>
<p><span id="more-7209"></span></p>
<h3>SQLite Database Tip</h3>
<p>For the first tip, which involves SQLite databases, this is the scenario: Let&#8217;s say you added a SQLite database to the project using a Build step and set the proper Folder/Subfolder, and then you connect to it from the <code>Session.Opening</code> event (or any other, for this case) in order to access its tables.</p>
<p>Even if you are running your Web app in local or debug mode (from the IDE) the connection to the SQLite database works, no matter if you&#8217;re typing the database file name in either upper or lowercase. Remember, when you are deploying the database to Xojo Cloud, you need to pass along the database name using the proper lowercase and uppercase characters in its original name.</p>
<p>Let&#8217;s suposse that the original database name on disk is &#8220;MyPrettyDatabase.sqlite&#8221;, then you&#8217;re using the following code in order to connect to it:</p>
<pre>#if DebugBuild then
    f=SpecialFolder.Desktop.Child("myprettydatabase.sqlite")
#else
    f=specialfolder.documents.child("myprettydatabase.sqlite")
#EndIf

BBDD.DatabaseFile=f

Try

    BBDD.Connect

catch e as IODatabaseException

End Try</pre>
<p>In this case, when running the web app from your computer everything will work fine (because most desktop operating systems use a case-insensitive file system, although Linux is often case-sensitive); but if you deploy the web app to Xojo Cloud you&#8217;ll find yourself with a database that does not connect. Fixing this is as simple as typing the string representing the database filename observing the uppercase characters existing in its original name:</p>
<pre>#if DebugBuild then
    f=SpecialFolder.Desktop.Child("myprettydatabase.sqlite")
#else
    f=specialfolder.documents.child("MyPrettyDatabase.sqlite")
#EndIf

    BBDD.DatabaseFile=f

Try

    BBDD.Connect

catch e as DatabaseException

End Try</pre>
<p><em><strong>SQLite Tip</strong>: Xojo 2020r1 updated to SQLite 3.31.1, which adds some <a href="https://blog.xojo.com/2020/08/31/sqlite-3-31-1-new-features/">cool new features</a>!</em></p>
<h3>MySQL/MariaDB Database Tip</h3>
<p>The second problem we&#8217;re solving involves the connection with MySQL/MariaDB databases hosted on a remote server from your Xojo Cloud app.</p>
<p>Although connecting to a remote MySQL database is <a href="https://documentation.xojo.com/api/databases/mysqlcommunityserver.html">well documented here</a>, let&#8217;s review. If you need to establish this kind of connection, remember to open the Xojo Cloud firewall port first.</p>
<p>For example, something like this code snippet will let the web app work when deployed on Xojo Cloud and when you are doing a local test running it from the IDE (debug mode):</p>
<pre>#If TargetXojoCloud
    Var fwp As New XojoCloud.FirewallPort(3306, XojoCloud.FirewallPort.Direction.Outgoing)
    fwp.Open
    If fwp.isOpen Then
        connectDatabase
    End If
#Else
    ConnectDatabase
#EndIf</pre>
<p>Where, in this case, ConnectDatabase is the method in charge of doing the real connection setting the usual parameters agains the MySQLCommunityServer instance.</p>


<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite 3.31.1 New Features</title>
		<link>https://blog.xojo.com/2020/08/31/sqlite-3-31-1-new-features/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Mon, 31 Aug 2020 19:44:06 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=7409</guid>

					<description><![CDATA[Xojo 2020r1 upgraded to SQLite 3.31.1. Notable new features include PRAGMA lists and generated columns aka computed columns!]]></description>
										<content:encoded><![CDATA[
<p>Xojo 2020 Release 1 upgraded <a href="https://documentation.xojo.com/api/databases/sqlitedatabase.html">SQLiteDatabase</a> to SQLite 3.31.1. The prior version of Xojo used SQLite 3.29.0. Although that seems like only a small jump there are a few notable new features that you can now use.</p>



<h2 class="wp-block-heading">Order Your Nulls</h2>



<p>You can now control where NULL values appear in columns when you use ORDER BY. Normally NULLs appear first in ascending sorts and last in descending sorts. But you can reverse that by using the NULLS FIRST or NULLS LAST syntax like this:</p>



<pre class="wp-block-preformatted">SELECT Name FROM Team ORDER BY Team NULLS LAST</pre>



<h2 class="wp-block-heading">PRAGMA Lists</h2>



<p>There are three new PRAGMA commands that return various meta data about SQLite:</p>



<ul class="wp-block-list"><li>PRAGMA function_list</li><li>PRAGMA module_list</li><li>PRAGMA pragma_list</li></ul>



<p>You won&#8217;t really use this in your code, but they can be useful as a sort of help in your database tool to show you what&#8217;s available. I think PRAGMA function_list will be the most useful one.</p>



<h2 class="wp-block-heading">Generated (Computed) Columns</h2>



<p>I&#8217;ve saved the best for last. You can now Add columns to your tables whose values are calculated from other column values using standard operators and built-in SQLite functions (see the function_list above).</p>



<p>SQLite calls these &#8220;generated columns&#8221;, but &#8220;computed columns&#8221; or &#8220;calculated columns&#8221; are other terms for them.</p>



<p>These columns can be either Virtual or Stored. A Virtual Generated Column is calculated each time it is accessed so it can be slower, especially if the calculation is complex. A Stored Virtual Column is calculated when the row is added or updated and saved in the database. This means it will take up space in the database file, but will return its result faster.</p>



<p>To create one of these columns you use the GENERATED command after the type followed by the calculation after the AS and ended with either VIRTUAL or STORED. For example:</p>



<pre class="wp-block-preformatted">CREATE TABLE Product (
  ID INTEGER PRIMARY KEY,
  Price REAL,
  Quantity INT,
  Total INT GENERATED AS (Price*Quantity) VIRTUAL
)</pre>



<p>You can INSERT some data into this table:</p>



<pre class="wp-block-preformatted">INSERT INTO Product (Price, Quantity) VALUES (5.00, 2)</pre>



<p>Now you can query the table and ask for the Total column:</p>



<pre class="wp-block-preformatted">SELECT Total FROM Product</pre>



<p>The result returns 10.</p>



<p>These type of columns are common in more powerful databases and it is great to see them in SQLite. Learn more about Generated Columns at the official SQLite doc page: <a href="https://sqlite.org/gencol.html">https://sqlite.org/gencol.html</a></p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>3 Steps to Seamlessly Deploy SQLite Projects on Desktop, Web &#038; iOS</title>
		<link>https://blog.xojo.com/2020/03/17/3-steps-to-seamlessly-deploy-sqlite-projects-on-desktop-web-ios/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Tue, 17 Mar 2020 10:00:25 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Desktop]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Xojo Cloud]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Object-Oriented]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=6725</guid>

					<description><![CDATA[This tutorial will show you how to deploy your SQLite based projects so they behave right on Desktop, Web and iOS, copying the database file to the right place on every target.]]></description>
										<content:encoded><![CDATA[<p>This tutorial will show you how to deploy your SQLite based projects so they behave right on Desktop, Web and iOS, copying the database file to the right place on every target.</p>
<h2>1. Adding the database file</h2>
<p>You probably created your SQLite database file using an external editor; so first add that file to your Xojo project.</p>
<p>You can do that in several ways, but usually it&#8217;s best to add a Build Step. This way, the file will be added automatically to the folder of your choice every time you compile your app. <em>Bonus: Doing this allows you to decide to use different paths when debugging or deploying your app.</em></p>
<p>In order to add a new Build Step in a <span style="text-decoration: underline;">Desktop</span> project select the target in the Build Settings then, from the contextual menu, choose the &#8220;Add to Build Settings &gt; Build Step &gt; Copy Files&#8221; option.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6726 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.37.51-300x70.png" alt="" width="300" height="70" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.37.51-300x70.png 300w, https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.37.51.png 655w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>The previous action will give you access to the Inspector Panel for the just-added item where you will be able to type a name for the Build Step, choose if the copy file action will be executed both for debugging or deployment and, most importantly, choose the location where the file should be copied when the app compiles.</p>
<p>In fact, the Destination menu contains a number of typical paths (or most relevant folders). For example, a good Destination option would be &#8220;Resources Folder&#8221;. Of course, don&#8217;t forget to add the database file itself using the buttons on the Build Editor toolbar.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6727 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.42.04-300x173.png" alt="" width="300" height="173" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.42.04-300x173.png 300w, https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.42.04.png 359w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<p>When you&#8217;re working with a <span style="text-decoration: underline;">Web project</span>, you&#8217;ll find exactly the same behavior, even if you choose to deploy with Xojo Cloud.</p>
<p>On <span style="text-decoration: underline;">iOS</span>, the only change is that you&#8217;ll have to choose the icon with an iPhone picture in it in order to access the Build Step contextual menu; in addition to the fact that every added resource needs to be signed with a certificate.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6728 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.43.45-300x47.png" alt="" width="300" height="47" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.43.45-300x47.png 300w, https://blog.xojo.com/wp-content/uploads/2020/03/Screenshot-2020-03-04-at-12.43.45.png 608w" sizes="auto, (max-width: 300px) 100vw, 300px" /></p>
<h2>2. Copying the database file to a &#8220;Working&#8221; folder</h2>
<p>You may think that the previous step is all you need to do, because if the database file is already copied in a well know path then you only need to provide that path as the DatabaseFile property on a new SQLiteDatabase or iOSSQLiteDatabase instance. But this is not the case.</p>
<p>They are many reasons you shouldn&#8217;t do that, specifically because the database would be open in read/write mode and if you write to that database file inside an application bundle, then you&#8217;ll be modifying a resource that would invalidate any certificate signature on your app.</p>
<p>The best thing to do is o detect every time you run the app if the database file has already been copied from the app bundle (or folder) into a target folder that doesn&#8217;t have an access problem when it is time to use the database. The Application Support folder is a good place for Desktop apps, while the Documents folder is fine for Xojo Cloud and iOS apps.</p>
<p>For example, if our database file is named &#8220;EddiesElectronics.sqlite&#8221; and our app name is &#8220;Xojotest&#8221;, then we can add the following code fragment into the Open Event Handler of a Desktop app:</p>
<pre>Var source As FolderItem = SpecialFolder.Resource("EddiesElectronics.sqlite")
Var name As String = app.ExecutableFile.name.NthField(".",1)

// We check if there is a folder with the App name in special Application Data
// if not, we create it and copy the database file from Resources bundle/directory
If Not (SpecialFolder.ApplicationData.Child(name).Exists And SpecialFolder.ApplicationData.Child(name).IsFolder) Then SpecialFolder.ApplicationData.Child(name).CreateFolder
If Not SpecialFolder.ApplicationData.child(name).child(source).exists Then source.CopyTo(SpecialFolder.ApplicationData.Child(name))

Try
  // Create a SQLiteDatabase instance and try to open our database file from
  // the path
  pDatabase = New SQLiteDatabase
  pDatabase.DatabaseFile = SpecialFolder.ApplicationData.Child(name).Child("EddiesElectronics.sqlite")
  pDatabase.Connect

Catch e As DatabaseException
  MessageBox e.Message
End Try</pre>
<p>For an iOS app, the code would be:</p>
<pre>Var source As Xojo.IO.FolderItem = xojo.io.SpecialFolder.GetResource("EddiesElectronics.sqlite")

// We check if there is our database file already copied on the Documents Sandbox folder
// if not, we copy the database file from Resources bundle/directory
If Not xojo.io.SpecialFolder.Documents.Child("EddiesElectronics.sqlite").Exists Then
  source.CopyTo(xojo.io.SpecialFolder.documents)
End If

Try
  // Create a SQLiteDatabase instance and try to open our database file from
  // the path
  pDatabase = New iosSQLiteDatabase

  Var f As FolderItem = xojo.io.SpecialFolder.Documents
  pDatabase.DatabaseFile = f.Child("EddiesElectronics.sqlite")
  Call pDatabase.Connect

Catch e As RuntimeException
  MessageBox e.Reason
End Try</pre>
<p>If you&#8217;re working on Xojo Cloud, the code will be even shorter. First, make sure that the Copy File Build Step has the following values in the Inspector Panel:</p>
<ul>
<li><strong>Destination:</strong> Contents Folder</li>
<li><strong>Subdirectory:</strong> Documents</li>
</ul>
<p>Then, the code will be:</p>
<pre>Try
  pDatabase = new SQLiteDatabase
  pDatabase.DatabaseFile = SpecialFolder.Documents.Child("EddiesElectronics.sqlite")
  pDatabase.connect
Catch e as RuntimeException
  MessageBox e.Reason
End Try</pre>
<p>What about a Web app that you host? That would mean you are in control about the folder/directory you want to use to store the app resources. Thus, it wouldn&#8217;t make much sense to automatize this process (but it is certainly doable following the same principles).</p>
<h2>3. Simplifying the process</h2>
<p>What we have seen already works, but that means that you need to change the file database name and probably that would change on every app you build. That also means that you&#8217;ll have to write the same code snippet again and again on every new app. Wouldn&#8217;t it be great to be able to extend the SQLiteDatabase and iOSSQLiteDatabase classes in order to simplify that?</p>
<p>Well, you can do that! Start by adding a new Module to the example project (for example one named &#8220;DatabaseExtensions&#8221;) with a couple of methods on it. The first method will be the one executed on our Desktop, Web and Console apps, because all of these targets use the SQLiteDatabase class.</p>
<p>So, add a new method using the following signature in the just-created module:</p>
<pre>OpenDatabase( databaseName as String )</pre>
<p>It extends the SQLiteDatabase class, adding a new method that takes as parameter the name of the file we want to copy on the &#8220;work&#8221; folder/directory.</p>
<p>The code you should type on this method is:</p>
<pre>pDatabase = New SQLiteDatabase

#If TargetDesktop Or TargetConsole Or TargetWeb Then

  Var source As FolderItem = SpecialFolder.Resource( databaseName )
  Var name As String = app.ExecutableFile.name.NthField(".",1)
  // We check if there is a folder with the App name in special Application Data
  // if not, we create it and copy the database file from Resources bundle/directory
  If Not (SpecialFolder.ApplicationData.Child(name).Exists And SpecialFolder.ApplicationData.Child(name).IsFolder) Then
SpecialFolder.ApplicationData.Child(name).CreateFolder
If Not SpecialFolder.ApplicationData.Child(nam).Child(Source).exists Then source.CopyTo(SpecialFolder.ApplicationData.Child(name))

  Try
    // Create a SQLiteDatabase instance and try to open our database file from
    // the path
    pDatabase.DatabaseFile = SpecialFolder.ApplicationData.Child(name).Child(databaseName)
    pDatabase.Connect

  Catch e As DatabaseException
    MessageBox e.Message
  End Try

#ElseIf TargetXojoCloud
  Try
    pDatabase.DatabaseFile = SpecialFolder.Documents.Child( databaseName )
    pDatabase.connect
  Catch e As RuntimeException
    MessageBox e.Reason
  End Try
#EndIf</pre>
<p>Of course, we need to add the &#8220;pDatabase&#8221; property to our module too: pDatabase As SQLiteDatabase</p>
<p>Now, you&#8217;ll only need to use:</p>
<pre>OpenDatabase("EddiesElectronics.sqlite")</pre>
<p>With the method selected in the Project Browser, click on the Attributes section of the Inspector Panel (the Cog Wheel icon), and uncheck the &#8220;iOS 64&#8221; checkbox. This way, that method will not be included when compiling for iOS apps.</p>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6729 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.49-281x300.png" alt="" width="281" height="300" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.49-281x300.png 281w, https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.49.png 420w" sizes="auto, (max-width: 281px) 100vw, 281px" /></p>
<p>Do the same thing with the &#8220;pDatabase&#8221; property, so it is only compiled on the supported targets.</p>
<p>The second method is the one we will be using for iOS apps. The method signature would be:</p>
<pre>OpenDatabase(databseName as String)</pre>
<p>And typing the following fragment of code in the associated Code Editor:</p>
<pre>pIOSDatabase = New iOSSQLiteDatabase

Var source As Xojo.IO.FolderItem = xojo.io.SpecialFolder.GetResource( databaseName )

// We check if there is our database file already copied on the Documents Sandbox folder
// if not, we copy the database file from Resources bundle/directory
If Not xojo.io.SpecialFolder.Documents.Child( databaseName ).Exists Then
  source.CopyTo(xojo.io.SpecialFolder.documents)
End If

Try
  // Create a SQLiteDatabase instance and try to open our database file from
  // the path

  Var f As FolderItem = xojo.io.SpecialFolder.Documents
  pIOSDatabase.DatabaseFile = f.Child( databaseName )
  Call db.Connect

Catch e As RuntimeException
  MessageBox e.Reason
End Try</pre>
<p><img loading="lazy" decoding="async" class="size-medium wp-image-6730 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.27-282x300.png" alt="" width="282" height="300" srcset="https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.27-282x300.png 282w, https://blog.xojo.com/wp-content/uploads/2020/03/Captura-de-pantalla-2020-03-09-a-las-6.55.27.png 423w" sizes="auto, (max-width: 282px) 100vw, 282px" /></p>
<p>Lastly, and with the method item still selected in the Project Browser, go to the Attributes section of the Inspector Panel and make sure that the &#8220;iOS 64&#8221; checkbox is the only one selected under the &#8220;Include In&#8221; section. This way, we make sure that the method will be compiled only on iOS targets.</p>
<p>And do the same thing with the &#8220;piOSDatabase&#8221;, so it is only compiled for iOS targets.</p>
<h2>To Summarize</h2>
<p>As we see, the use of Modules in combination with OOP Class Extension is a good way to get more flexibility when developing your apps; using a common function (or method) name no matter if you are working on Desktop, Web or iOS. Additionally, that leads to a more convenient reutilization of your codeand, of course, less code to maintain through all our projects!</p>
<p>(You can find this article in Spanish <a href="https://www.aprendexojo.com/2020/03/prepara-bases-de-datos-sqlite-para-despliegue-en-desktop-web-y-ios/">here</a>)</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Tip: SQLite in RAM … to improve speed!</title>
		<link>https://blog.xojo.com/2019/02/11/tip-sqlite-in-ram-to-improve-speed/</link>
		
		<dc:creator><![CDATA[Javier Menendez]]></dc:creator>
		<pubDate>Mon, 11 Feb 2019 10:00:18 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5399</guid>

					<description><![CDATA[One technique is the creation of a new in-memory based SQLite database, where we will be able to copy the table (or tables) we are interested in getting the maximum speed possible with. Continue reading to see how to do this.]]></description>
										<content:encoded><![CDATA[<p>It&#8217;s very usual to use encrypted <b>SQLite</b> databases in our Xojo projects where we expect to get the maximum read speed from them. But the truth is that encrypting the data in these databases can introduce a penalty in our queries, both from read and writing/updating data to them. How can we improve this? One technique is the creation of a new in-memory based SQLite database, where we will be able to copy the table (or tables) we are interested in getting the maximum speed possible with. Continue reading to see how to do this.<span id="more-5399"></span></p>
<p>You can further modify this technique so you can work with your databases in a <em>mixed</em> way; that is, where we want to simultaneously execute a query involving both an encrypted database table and an in-memory table database.</p>
<p>But for this example code we are only focused on opening an encrypted SQLite database (based on disk) as a new SQLite class instance, and using next a SQL sentence to create a new in-memory database (named <code>RAMDB</code> in the example), creating the same table on the RAM database next and then copying the data from the <em>source</em> table during the process.</p>
<p>From that time on, you will be able to use the new table on RAM at light speed!</p>
<p>Another SQL command you might find of interest, and that you can use in all your SQLite databases where you expect to get a gain in the read speed, is to use the exclusive mode, using for that <code>PRAGMA LOCKING_MODE = Exclusive</code>.</p>
<p>However, and focusing on the tip itself, this is the snippet of code you can use:</p>
<pre>Var db As SQLiteDatabase = New SQLiteDatabase
db.DatabaseFile =  // Assign here a FolderItem to the SQLite database file on disk
db.EncryptionKey = "aes256:" +  // Add here a String with the same password that the one used to encrypt the data
If db.Connect = False Then
  Var re As New RuntimeException
  re.message = "Error trying to connect to the database"
  Raise re
End If
db.ExecuteSQL("PRAGMA LOCKING_MODE = Exclusive") // Improves the read access to the database

// We create a in-memory database, 'attaching' it with the disk based SQLite database
db.ExecuteSQL("attach database ':memory:' as 'RAMDB'")

// Copying all the contents from the source table
// to the newly created table on the RAM SQLite database

db.ExecuteSQL("create table RAMDB.product_table as select * from main.product_table")</pre>
<p>As you can see, the second line of code expects a valid <code>FolderItem</code> instance pointing to the SQLite database on disk. In addition, you need to provide the String to the password used originally to encrypt the data on the source database. This example assumes that this has been done using the <b>AES 256</b> option, stronger than the one using a length of 128 bits and the only option available before Xojo 2018r1.</p>
<p>Finally, in the last sentence <code>db.SQLExecute</code> you&#8217;ll have to change the table name you want to copy from the source database to the new RAM based one (<code>product_table</code> in the example).</p>
<p><em>Javier Rodri­guez has been the Xojo Spanish Evangelist since 2008, he’s also a Developer, Consultant and Trainer who has be using Xojo since 1998. He manages <a href="http://www.aprendexojo.com">AprendeXojo.com</a> and is the developer behind the GuancheMOS plug-in for Xojo Developers, Markdown Parser for Xojo, HTMLColorizer for Xojo and the Snippery app, among others.</em></p>
<p>*<a href="https://www.aprendexojo.com/2019/01/truco-sqlite-en-ram-mejora-al-maximo-el-rendimiento/">Read this post in Spanish</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite is not a server</title>
		<link>https://blog.xojo.com/2019/01/10/sqlite-is-not-a-server/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Thu, 10 Jan 2019 10:00:54 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web Service]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5299</guid>

					<description><![CDATA[If you are using SQLite you might be trying to share your database. What are your options when you want to be able to share your database?  ]]></description>
										<content:encoded><![CDATA[<p>People often ask about a way to share a <a href="http://www.sqlite.org">SQLite</a> database across multiple apps. Essentially they want to know how to use SQLite as a server and the most common questions relate to putting a SQLite database file on a shared network drive and accessing the database file from apps running on multiple computers. This is a really bad idea, as even the SQLite folks will tell you. I&#8217;ll quote the relevant section from their &#8220;<a href="https://www.sqlite.org/whentouse.html">When to use SQLite</a>&#8221; page:</p>
<blockquote><p><strong>Situations Where A Client/Server RDBMS May Work Better</strong></p>
<p><strong>Client/Server Applications</strong></p>
<p>If there are many client programs sending SQL to the same database over a network, then use a client/server database engine instead of SQLite. SQLite will work over a network filesystem, but because of the latency associated with most network filesystems, performance will not be great. Also, file locking logic is buggy in many network filesystem implementations (on both Unix and Windows). If file locking does not work correctly, two or more clients might try to modify the same part of the same database at the same time, resulting in corruption. Because this problem results from bugs in the underlying filesystem implementation, there is nothing SQLite can do to prevent it.</p>
<p>A good rule of thumb is to avoid using SQLite in situations where the same database will be accessed directly (without an intervening application server) and simultaneously from many computers over a network.</p></blockquote>
<p>So what are your options when you want to share your database?</p>
<p>If you want to stick with SQLite then you&#8217;ll need to put something in front of it that can handle requests from multiple client apps. The most obvious solution is to create a web service by using a web app with WebApplication.HandleURL (or HandleSpecialURL). The web app can accept requests from multiple client apps (or any type &#8212; desktop, web, mobile, etc.), fetch the data requested from the SQLite database and then send it back as JSON. This works because the web app is the only app that is connected to the SQLite database.</p>
<p>The <a href="https://documentation.xojo.com/UserGuide:Eddie%27s_Electronics_Sample_Web_Service">Eddie&#8217;s Electronics Web Service sample</a> shows you how you might set this up: Examples/Communication/Web Services/EddiesWebService</p>
<p>Another option for setting up your own database web service is to use the <a href="https://aloe.zone">Aloe open-source project</a>, which gives you a robust framework for building web services.</p>
<p>To learn more about database web services, check out the <a href="https://youtu.be/X58zSmm2iSE">Making Database Web Services video</a>.</p>
<p>By the way, this is also why a regular web app can safely use SQLite with multiple users &#8212; the web app manages the multiple users but is the only app that is connected to the SQLite database.</p>
<p>If you want to stick with SQLite but would rather not create a web service, another option to consider is to use a product that puts a database server around SQLite. <a href="https://www.sqlabs.com/cubesql.php">CubeSQL</a> and <a href="https://www.valentina-db.com/en/sqlite-database-server">Valentina</a> have products available that can do this.</p>
<p>Your final option is to switch to an actual database server. PostgreSQL and MySQL are popular alternatives.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite 3.25 Adds Window Functions and Improves ALTER TABLE</title>
		<link>https://blog.xojo.com/2018/12/18/sqlite-3-25-adds-window-functions-and-improves-alter-table/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 18 Dec 2018 10:00:15 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=5142</guid>

					<description><![CDATA[Xojo 2018 Release 4 updated SQLite to 3.25. The SQLite 3.25 release had two significant changes: Window Functions and an improved ALTER TABLE command. ALTER&#8230;]]></description>
										<content:encoded><![CDATA[<p>Xojo 2018 Release 4 updated SQLite to 3.25. The <a href="https://www.sqlite.org/releaselog/3_25_0.html">SQLite 3.25 release</a> had two significant changes: Window Functions and an improved ALTER TABLE command.</p>
<p><span id="more-5142"></span></p>
<h2>ALTER TABLE</h2>
<p>If you&#8217;ve been using SQLite for a while you probably know that the ALTER TABLE command has always been pretty restrictive. It really only let you change the table name or add new columns. You could not modify or remove columns. This meant that in order to modify or remove columns from a table you typically used a multi-step process of creating the new table the way you wanted, copying the data to it and then renaming the two tables so the new table now has the name of the original table. It was a hassle. And because this was manual it would break any triggers or views that used the old name.</p>
<p>Now with SQLite 3.25 you can directly rename columns on a table, which will update triggers and views as necessary.</p>
<p>The syntax is as you might expect:</p>
<pre>ALTER TABLE MyTable RENAME COLUMN OldColumn TO NewColumn;</pre>
<p>In Xojo code you send this command to the database using the SQLExecute method. Here&#8217;s an example that changes a column name:</p>
<pre>Dim sql As String = "ALTER TABLE Team RENAME COLUMN Coach To HeadCoach;"
DB.SQLExecute(sql)</pre>
<p>Sadly you still cannot remove a column so you&#8217;ll have to resort to the manual method described above.</p>
<h2>Window Functions</h2>
<p>According to the SQLite docs:</p>
<blockquote><p>A window function is a special SQL function where the input values are taken from a &#8220;window&#8221; of one or more rows in the results set of a SELECT statement.</p></blockquote>
<p>SQLite now has these built-in Window functions:</p>
<ul>
<li>row_number()</li>
<li>rank()</li>
<li>dense_rank()</li>
<li>percent_rank()</li>
<li>cume_dist()</li>
<li>ntile(N)</li>
<li>lag(expr), lag(expr, offset), lag(expr, offset, default)</li>
<li>lead(expr), lead(expr, offset), lead(expr, offset, default)</li>
<li>first_value(expr)</li>
<li>last_value(expr)</li>
<li>nth_value(expr, N)</li>
</ul>
<p>This example uses the row_number function to assign a row number based on ordered City names while still ordering the overall results by team name:</p>
<p>SELECT Name, City, row_number() OVER (ORDER By City) AS row_num FROM Team ORDER BY Name;</p>
<p>Window Functions are powerful and can get complex quickly. Read more about them at the official <a href="https://www.sqlite.org/windowfunctions.html">SQLite Window Function doc page</a>.</p>
<p>Xojo 2018 Release 4 includes SQLite 3.25.3 so be sure to upgrade to get access to these great new SQLite improvements. <a href="https://www.xojo.com/download/">Download</a> Xojo 2018 Release 4 for free today.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>#JustCode Challenge Week 9 &#8211; Quote Web Service</title>
		<link>https://blog.xojo.com/2018/08/17/justcode-challenge-week-9-quote-web-service/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Fri, 17 Aug 2018 10:00:24 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[#JustCode]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=4829</guid>

					<description><![CDATA[We're wrapping up week 9 of #JustCode with a web app that demonstrates a web service, JSON and SQLite. The web app functions as both an app with a UI and a web service. It lets you enter your own quotes which are saved in a SQLite database. The web service randomly fetches a quote and returns it as JSON.]]></description>
										<content:encoded><![CDATA[<p>We&#8217;re wrapping up week 9 of #JustCode with a web app that demonstrates a web service, JSON and SQLite. The web app functions as both an app with a UI and a web service. It lets you enter your own quotes which are saved in a SQLite database. The web service randomly fetches a quote and returns it as JSON.</p>
<p><span id="more-4829"></span></p>
<p><img loading="lazy" decoding="async" class="size-full wp-image-4831 aligncenter" src="https://blog.xojo.com/wp-content/uploads/2018/08/2018-08-15_12-22-31.png" alt="" width="591" height="490" /></p>
<p>The SQLite database has just a single table called Quote with this structure:</p>
<pre>CREATE TABLE Quote (
ID INTEGER NOT NULL,
QuoteText TEXT,
QuoteSource TEXT, 
PRIMARY KEY (ID)
);</pre>
<p>To randomly fetch a single quote from the table, this SQL is used:</p>
<pre>SELECT QuoteText, QuoteSource FROM Quote ORDER BY RANDOM() LIMIT 1;</pre>
<p>As companion apps, I&#8217;ve also included simple desktop and iOS apps that call the web service to display a quote.</p>
<p>The raw JSON that is returned looks like this:</p>
<pre>{"QuoteText":"Simple things should be simple. Complex things should be possible.","QuoteSource":"Alan Kay"}</pre>
<p>I&#8217;ve published a version of this on <a href="https://www.xojo.com/cloud/">Xojo Cloud</a>. <a href="http://demos.xojo.com/QuoteService/">Access the app</a>.</p>
<p>Access the web service <a href="http://demos.xojo.com/QuoteService/index.cgi/api/quote">here</a>.</p>
<p>You can <a href="http://files.xojo.com/JustCode/QuoteService.zip">download the projects</a> or check it all out <a href="https://gitlab.com/xojo/QuoteService">on GitLab</a>.</p>
<p>Add your #JustCode project to the <a href="https://forum.xojo.com/49401-just-code-challenge-week-9-projects">week 9 forum conversation</a>.</p>
<p>Download and check out earlier projects:</p>
<ul>
<li>Week 8: <a href="https://blog.xojo.com/2018/08/10/justcode-challenge-week-8-jumpstart-app-launcher/">JumpStart App Launcher</a></li>
<li>Week 7: <a href="https://blog.xojo.com/2018/08/03/justcode-challenge-week-7-pitch-tracker/">Pitch Tracker</a></li>
<li>Week 6: <a href="https://blog.xojo.com/2018/07/27/justcode-challenge-week-6-bubble-popper/">Bubble Popper</a></li>
<li>Week 5: <a href="https://blog.xojo.com/2018/07/20/justcode-challenge-week-5-math-quiz/">Math Quiz</a></li>
<li>Week 4: <a href="https://blog.xojo.com/2018/07/13/justcode-challenge-week-4-mini-golf-scorekeeper/">Mini-Golf ScoreKeeper</a></li>
<li>Week 3: <a href="https://blog.xojo.com/2018/07/06/just-code-challenge-week3/">Dogs Up!</a></li>
<li>Week 2: <a href="https://blog.xojo.com/2018/06/29/just-code-challenge-week2/">Password Generator</a></li>
<li>Week 1: <a href="https://blog.xojo.com/2018/06/22/just-code-challenge-week1/">Color Picker</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>SQLite Rocks, Let Us Tell You Why</title>
		<link>https://blog.xojo.com/2017/10/03/sqlite-rocks-let-us-tell-you-why/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 03 Oct 2017 07:39:30 +0000</pubDate>
				<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Beginner Tips]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2690</guid>

					<description><![CDATA[SQLite is a great database to use for all kinds of apps, here are 8 reasons why it rocks.]]></description>
										<content:encoded><![CDATA[
<p>Here at Xojo, we <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2764.png" alt="❤" class="wp-smiley" style="height: 1em; max-height: 1em;" />&nbsp;<a href="http://www.sqlite.org">SQLite</a>&nbsp;so much &#8211; It&#8217;s truly a great database to use for all kinds of apps.</p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter"><img decoding="async" src="https://www.xojo.com/resources/images/sqlite/sqlite.gif" alt=""/></figure>
</div>


<p>Here are 8 reasons why you should be using SQLite with your apps:</p>



<span id="more-2690"></span>



<p><strong>1. It is fast</strong></p>



<p>SQLite is an embedded database so the database engine gets built right into your app. It is also designed for incredible speed. It can handle millions of rows with ease.</p>



<p><strong>2. It is typeless</strong></p>



<p>Unlike other databases, SQLite does not care what type of data you put into a column. In fact, it really doesn&#8217;t use types at all! Columns are assigned an &#8220;affinity&#8221; of INTEGER, REAL, TEXT and BLOB which helps determine how they are used for queries and functions. But you can stick text data into an integer column without a problem. You can read more about SQLite&#8217;s unique handling of Data Types on their <a href="http://www.sqlite.org/datatype3.html" target="_blank&quot;" rel="noopener">documentation page</a>.</p>



<p><strong>3. It is cross-platform</strong></p>



<p>SQLite works on every platform imaginable, including: Windows, macOS, Linux, Raspberry Pi, web, iOS and Android. Additionally, the database files themselves are cross-platform. So if you create a database and populate with data on iOS, you can move the file over to Windows and be able to read, write and otherwise use it without trouble. This makes SQLite a great fit for cross-platform development tools like Xojo.</p>



<p><strong>4. It is public domain</strong></p>



<p>Because it is public domain, SQLite is complete free to use with no restrictions of any kind. And the <a href="https://www.sqlite.org/src/doc/trunk/README.md">full source code is readily available</a>, of course.</p>



<p><strong>5. It works with most programming languages</strong></p>



<p>Most programming languages have built-in support for SQLite, including: Delphi, C, C#, C++, Go, Java, JavaScript, LiveCode, Lue, Objective-C, Perl, PHP, Python, Ruby, Visual Basic and Xojo. With Xojo you can use SQLite with macOS, Windows, Linux, web, console, iOS and Android apps.</p>



<p><strong>6. It is updated often</strong></p>



<p>SQLite is a mature database with few bugs, but it is <a href="https://www.sqlite.org/news.html">updated often</a>&nbsp;to ensure it remains at its best quality. If any bugs sneak in, they are quickly squashed.</p>



<p><strong>7. It is fast</strong></p>



<p>SQLite is so fast that it is worth saying again. Seriously, it is fast. Don&#8217;t use a text file or JSON or some other thing that will likely be much slower, especially when the files get large. Use SQLite and you&#8217;ll be happier.</p>



<p><strong>8. It is used everywhere</strong></p>



<p>It is a good bet that apps you rely on are using SQLite in some way. It is a great storage mechanism for preferences, general app data and can even be used as the app file format itself. For example, Apple Mail uses SQLite to save email messages and Firefox uses SQLite databases to store much of its profile information.</p>



<p>You can <a href="http://www.xojo.com/download">download Xojo for free</a> to start making apps that use <a href="https://documentation.xojo.com/topics/databases/database_basics_for_beginners.html">SQLite</a>. For more information, check out these videos:</p>



<ul class="wp-block-list">
<li><a href="http://developer.xojo.com/webinar-using-sqlite">Using SQLite</a></li>



<li><a href="http://developer.xojo.com/webinar-sqlite">SQLite Features</a></li>



<li><a href="http://developer.xojo.com/webinar-advanced-sqlite">Advanced SQLite</a></li>
</ul>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><em>Updated February 2024 to include Xojo Android.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Appreciating SQL</title>
		<link>https://blog.xojo.com/2017/05/09/appreciating-sql/</link>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 09 May 2017 19:51:27 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">http://blog.xojo.com/?p=2651</guid>

					<description><![CDATA[Noted recently at the SQLizer blog, the SQL language was first created 43 years ago. And what is remarkable about that is that SQL is still used today. ]]></description>
										<content:encoded><![CDATA[<p>Noted recently at the <a href="http://blog.sqlizer.io/posts/sql-43/">SQLizer blog</a>, the SQL language was first created 43 years ago. And what is remarkable about that is that SQL is still used today. According to the <a href="https://stackoverflow.com/insights/survey/2017">Stack Overflow 2017 developer survey</a> it is the #2 programming language. Not many languages remain in use for such a long period of time. Although we’re happy to also note that Xojo celebrated our 20th anniversary in 2016!</p>
<p><span id="more-2651"></span></p>
<p>One reason that SQL might rank so high is that it is not really a single language. Although the term SQL is used to refer to the default language used with every relational database, each version is different. SQL actually means <a href="https://en.wikipedia.org/wiki/SQL">Structured Query Language</a>, not Standard Query Language as I often hear people refer to it. Every database that uses SQL also uses its own variant of SQL and these variants differ by just enough to be annoying, although the core commands are mostly the same. It reminds me of how BASIC was in the 1970s and 80s with different versions for each computer with nothing but the most basic (pun intended) compatibility between them.</p>
<p>Even though SQL is a programming language, it is not like languages you are likely most familiar with. You use SQL to write database queries that return sets of data so it works differently than just about any other language you might be familiar with (although some versions add some procedural commands).</p>
<p>For example if you wanted to process a bunch of rows in a typical language you might write code like this to loop through all the data:</p>
<pre>For Each i As Integer = 0 To row.Ubound
 row(i) = row(i) * 2
Next</pre>
<p>In SQL that data would be in a table and you would change the values of all the rows by using an UPDATE command:</p>
<pre>UPDATE data SET value = value * 2;</pre>
<p>Both effectively do a loop, but they don’t look all that similar.</p>
<p>Another interesting thing about SQL is that it really is a companion to any programming language you use to make apps. Since no one would ever make an actual app using just SQL, but most apps need a database of some kind, SQL becomes the 2nd language that you have to know alongside your primary language.</p>
<p>Xojo works with SQL by using one of its database classes to send SQL directly to the database you are using. For example, to work with a SQLite database you would use the SQLiteDatabase class for desktop, web or console app or the iOSSQLiteDatabase class for iOS apps. Those classes each have two methods to send SQL commands to the database: SQLSelect and SQLExecute. Essentially SQLSelect is used for SQL commands that return sets of data and SQLExecute is used for commands that do an action (such as create a table).</p>
<p>Like other programming languages, Xojo does not care what database you use nor does it care what SQL you are sending to it.</p>
<p>You can learn about some common SQL commands in the <a href="http://developer.xojo.com/userguide/database-operations">Database Operations</a> topic of the User Guide at the Xojo Dev Center.</p>
<p>&nbsp;</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Database Usage with Web Apps</title>
		<link>https://blog.xojo.com/2016/06/28/database-usage-with-web-apps/</link>
					<comments>https://blog.xojo.com/2016/06/28/database-usage-with-web-apps/#comments</comments>
		
		<dc:creator><![CDATA[Paul Lefebvre]]></dc:creator>
		<pubDate>Tue, 28 Jun 2016 09:35:00 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQLite]]></category>
		<guid isPermaLink="false">http://blogtemp.xojo.com/2016/06/15/database-usage-with-web-apps/</guid>

					<description><![CDATA[A quick tip on how best to connect to databases from web apps.]]></description>
										<content:encoded><![CDATA[<p>Using databases with web apps is not much different than using them with desktop apps, but there are a few things to keep in mind. The most important thing to note is that a web app allows multiple users. This means you&#8217;ll want your database connection to be unique for each user that connects to the web app, rather than global to the app itself (as is common in desktop apps). The simplest way to ensure this is to create the connection to your database in the WebSession.Open event handler, saving a reference to the connection as a property that you add to WebSession.</p>
<p><span id="more-265"></span></p>
<p>A property such as &#8220;DB As SQLiteDatabase&#8221; on the Session object works well. Then in its Open event handler, you actually connect to the database:</p>
<pre>Dim dbFile As FolderItem = GetFolderItem("MyDatabase.sqlite")
DB = New SQLiteDatabase
DB.DatabaseFile = dbFile
If Not db.Connect Then
 ' Display an error page and log the error
 ' You should not show specifics of the error to users
 ErrorPage.Show
End If</pre>
<p>In the rest of your project, you can refer to the database like this:</p>
<pre>Session.DB</pre>
<p>The second thing to remember is that because a web app can be accessed by many more users it is more susceptible to <a href="http://blog.xojo.com/2016/02/18/avoiding-sql-injection/">SQL Injection</a>. To limit your exposure here, you should always use SQL Prepared Statements with any SQL statements that contain parameters with values from user-entered input.</p>
<p>To learn more about databases and web apps, view the <a href="http://developer.xojo.com/database-usage-with-web-apps">Database Usage with Web Apps</a> topic in the Dev Center and watch our <a href="http://developer.xojo.com/webinar-connecting-to-db">Webinar: Connecting to Databases</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.xojo.com/2016/06/28/database-usage-with-web-apps/feed/</wfw:commentRss>
			<slash:comments>6</slash:comments>
		
		
			</item>
	</channel>
</rss>
