Vanilla only supports MySQL. It has a generic SQL driver implementation built on top of PDO to potentially allow for other databases (which you can see in
/library/databases). However, at this time, the Vanilla team has no plans to support additional databases.
The best way to access the database is via existing models. For instance, to get a list of discussions, use the
get method in the
DiscussionModel. You can rely on model-based access to already be optimized for performance and utilize caching if it’s available.
SQL object supports chaining. You can call it with
Here’s a simple example that gets a single discussion by its ID. We write its pieces in the order of a SQL statement, but they can be called in any order up to the
get() is the call that fires the built query.
Note that this is an impractical query to use in your addon, because this functionality already exists in a model:
$discussionModel = new DiscussionModel();
Always use pre-existing calls in models when they are available for better performance and forward-compatibility.
Here’s an example of a complex select that pulls out all the stops:
->select('iu.Name', '', 'InsertName')
->join('Conversation c', 'cm.ConversationID = c.ConversationID')
->join('UserConversation uc', 'c.ConversationID = uc.ConversationID and uc.UserID = '.$viewingUserID, 'left')
->join('User iu', 'cm.InsertUserID = iu.UserID', 'left')
->where('uc.DateCleared is null')
->orWhere('uc.DateCleared <', 'cm.DateInserted', true, false)
Notice the use of limit, offset, where groups, where conditions including less than & null, aliasing, and multiple joins.
Updates and inserts
An insert is a single step that takes the table name and an array of values to insert as parameters:
'ConversationID' => $conversationID,
'UserID' => $targetUserID
An update requires setting the table in
update, ends with a
put (much like the select’s ending
query() method allows for sending unfiltered SQL queries to the database. This is strongly discouraged because it can easily cause security flaws, performance problems, and compatibility problems.
Gdn::sql()->query("select * from GDN_Comments");
Vanilla allows you to define database structures in code. Use the
Gdn::structure() method to use this object. Here we’ll look at part of the definition of the User table as an example:
->column('Name', 'varchar(50)', false, 'key')
->column('ShowEmail', 'tinyint(1)', '0')
->column('Gender', array('u', 'm', 'f'), 'u')
->column('Preferences', 'text', true)
->column('DateOfBirth', 'datetime', true)
->column('Score', 'float', NULL)
column() takes 4 parameters: name, type, nulldefault (
true to allow nulls,
false to not - any other value becomes the default with disallowed nulls), and keytype (‘primary’, ‘key’, ‘index’, ‘unique’, or ‘fulltext’ - defaults to false).
primaryKey() creates an auto-incrementing column. The Gender column uses an array to create an
enum type; the rest are self-explanatory.
set() method takes 2 parameters which should nearly always be false, which is their default. The first is
$explicit which is whether to force the structure of the table to match exactly the definition above. The second is
$drop which is whether to drop and recreate the table.