The official SingleStore Laravel driver.

Last update: Jun 29, 2022

SingleStore Driver for Laravel

This repository contains a SingleStore Driver for Laravel.

This package is currently in a pre-release beta, please use with caution and open any issues that you run into.

Install

You can install the package via composer:

composer require singlestore/singlestore-laravel

Usage

To enable the driver, head to your config/database.php file and create a new entry for SingleStore in your connections, and update your default to point to that new connection:

[
    'default' => env('DB_CONNECTION', 'singlestore'),

    'connections' => [
        'singlestore' => [
            'driver' => 'singlestore',
            'url' => env('DATABASE_URL'),
            'host' => env('DB_HOST'),
            'port' => env('DB_PORT'),
            'database' => env('DB_DATABASE'),
            'username' => env('DB_USERNAME'),
            'password' => env('DB_PASSWORD'),
            'unix_socket' => env('DB_SOCKET'),
            'charset' => 'utf8mb4',
            'collation' => 'utf8mb4_unicode_ci',
            'prefix' => '',
            'prefix_indexes' => true,
            'strict' => true,
            'engine' => null,
            'options' => extension_loaded('pdo_mysql') ? array_filter([
                PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
                PDO::ATTR_EMULATE_PREPARES => true,
            ]) : [],
        ],
    ]
]

The SingleStore driver is an extension of the MySQL driver, so you could also just change your driver from mysql to singlestore.

In case you want to store failed jobs in SingleStore, then make sure you also set it as the database in your config/queue.php file. At which point, you may actually preffer to set DB_CONNECTION='singlestore' in your environment variables.

'failed' => [
    'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
    'database' => env('DB_CONNECTION', 'singlestore'),
    'table' => 'failed_jobs',
],

Migrations

This driver provides many SingleStore specific methods for creating or modifying tables. They are listed below. For more information see the Create Table docs on SingleStore.

Rowstore Tables

To create a rowstore table, use the rowstore method.

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();

    // ...
});

Reference Tables

To create a reference table, you may use the reference method.

Schema::create('table', function (Blueprint $table) {
    $table->reference();

    // ...
});

Global Temporary Tables

To create a global temporary table, you may use the global method on the table.

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();
    $table->temporary();
    $table->global();

    // ...
});

You may also use either of the following two methods:

// Fluent
$table->rowstore()->temporary()->global();

// As an argument to `temporary`.
$table->temporary($global = true);

Sparse Columns

You can mark particular columns as sparse fluently by appending sparse to the column's definition.

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();

    $table->string('name')->nullable()->sparse();
});

Sparse Tables

You can mark particular entire tables as sparse fluently by appending sparse to the column's definition.

Schema::create('table', function (Blueprint $table) {
    $table->rowstore();

    $table->string('name');

    $table->sparse();
});

Shard Keys

You can add a shard key to your tables using the standalone shardKey method, or fluently by appending shardKey to the column definition.

Schema::create('table', function (Blueprint $table) {
    $table->string('name');

    $table->shardKey('name');
});

Schema::create('table', function (Blueprint $table) {
    $table->string('name')->shardKey();
});

Schema::create('table', function (Blueprint $table) {
    $table->string('f_name');
    $table->string('l_name');

    $table->shardKey(['f_name', 'l_name']);
});

Sort Keys

You can add a sort key to your tables using the standalone sortKey method, or fluently by appending sortKey to the column definition.

Schema::create('table', function (Blueprint $table) {
    $table->string('name');

    $table->sortKey('name');
});

Schema::create('table', function (Blueprint $table) {
    $table->string('name')->sortKey();
});

Schema::create('table', function (Blueprint $table) {
    $table->string('f_name');
    $table->string('l_name');

    $table->sortKey(['f_name', 'l_name']);
});

Series Timestamps

To denote a column as a series timestamp, use the seriesTimestamp column modifier.

Schema::create('table', function (Blueprint $table) {
    $table->datetime('created_at')->seriesTimestamp();

    // Or make it sparse
    $table->datetime('deleted_at')->nullable()->seriesTimestamp()->sparse();
});

Computed Columns

SingleStore does not support virtual computed columns. You must use Laravel's storedAs method to create a persisted computed column.

Schema::create('test', function (Blueprint $table) {
    $table->integer('a');
    $table->integer('b');
    $table->integer('c')->storedAs('a + b');
});

Testing

Execute the tests using PHPUnit

./vendor/bin/phpunit

To test against an active SingleStore database, create a .env file and populate the following variables:

DB_DATABASE=
DB_USERNAME=
DB_PASSWORD=
DB_HOST=

Now when executing your tests, enable the integration tests by running

HYBRID_INTEGRATION=1 ./vendor/bin/phpunit

License

This library is licensed under the Apache 2.0 License.

Resources

User agreement

SINGLESTORE, INC. ("SINGLESTORE") AGREES TO GRANT YOU AND YOUR COMPANY ACCESS TO THIS OPEN SOURCE SOFTWARE CONNECTOR ONLY IF (A) YOU AND YOUR COMPANY REPRESENT AND WARRANT THAT YOU, ON BEHALF OF YOUR COMPANY, HAVE THE AUTHORITY TO LEGALLY BIND YOUR COMPANY AND (B) YOU, ON BEHALF OF YOUR COMPANY ACCEPT AND AGREE TO BE BOUND BY ALL OF THE OPEN SOURCE TERMS AND CONDITIONS APPLICABLE TO THIS OPEN SOURCE CONNECTOR AS SET FORTH BELOW (THIS “AGREEMENT”), WHICH SHALL BE DEFINITIVELY EVIDENCED BY ANY ONE OF THE FOLLOWING MEANS: YOU, ON BEHALF OF YOUR COMPANY, CLICKING THE “DOWNLOAD, “ACCEPTANCE” OR “CONTINUE” BUTTON, AS APPLICABLE OR COMPANY’S INSTALLATION, ACCESS OR USE OF THE OPEN SOURCE CONNECTOR AND SHALL BE EFFECTIVE ON THE EARLIER OF THE DATE ON WHICH THE DOWNLOAD, ACCESS, COPY OR INSTALL OF THE CONNECTOR OR USE ANY SERVICES (INCLUDING ANY UPDATES OR UPGRADES) PROVIDED BY SINGLESTORE. BETA SOFTWARE CONNECTOR

Customer Understands and agrees that it is being granted access to pre-release or “beta” versions of SingleStore’s open source software connector (“Beta Software Connector”) for the limited purposes of non-production testing and evaluation of such Beta Software Connector. Customer acknowledges that SingleStore shall have no obligation to release a generally available version of such Beta Software Connector or to provide support or warranty for such versions of the Beta Software Connector for any production or non-evaluation use.

NOTWITHSTANDING ANYTHING TO THE CONTRARY IN ANY DOCUMENTATION, AGREEMENT OR IN ANY ORDER DOCUMENT, SINGLESTORE WILL HAVE NO WARRANTY, INDEMNITY, SUPPORT, OR SERVICE LEVEL, OBLIGATIONS WITH RESPECT TO THIS BETA SOFTWARE CONNECTOR (INCLUDING TOOLS AND UTILITIES).

APPLICABLE OPEN SOURCE LICENSE: Apache 2.0

IF YOU OR YOUR COMPANY DO NOT AGREE TO THESE TERMS AND CONDITIONS, DO NOT CHECK THE ACCEPTANCE BOX, AND DO NOT DOWNLOAD, ACCESS, COPY, INSTALL OR USE THE SOFTWARE OR THE SERVICES.

GitHub

https://github.com/singlestore-labs/singlestore-laravel-driver
Comments
  • 1. Drop tables one by one

    Dropping more than one table in a single query is not supported by SingleStore, as we can see in https://github.com/singlestore-labs/singlestore-laravel-driver/issues/3#issuecomment-1151213371.

    This draft PR solves this issue, but the solution can be improved.

    Instead of the one item array per table, I tried using $this->grammar->compileDrop($table) from MySqlGrammar, but it needs the Blueprint which I don't really know how to get.

    I'm leaving this draft PR here, at least as a proof of concept.

    Reviewed by fgilio at 2022-06-09 15:18
  • 2. Use client-side prepared statements

    This partially fixes artisan migrate:fresh reported in https://github.com/singlestore-labs/singlestore-laravel-driver/issues/3 by replicating SingleStore's official recommendation.

    More information on why this is needed here.

    Reviewed by fgilio at 2022-06-09 14:56
  • 3. Add Package Auto-Discovery

    Hi!

    Consider this a draft and just a POC, feel free to close it right away.

    I got this minor issue when first trying the package: Screen Shot 2022-06-08 at 14 32 51

    And quickly got it working by adding the provider in app.php.

    Thanks!

    Reviewed by fgilio at 2022-06-08 17:35
  • 4. Add support for whereFullText

    Hi Aaron!

    Another draft PR here, it's missing tests and the implementation is just bare bones.

    I found SingleStore's syntax is slightly different from MySQL, so the version from MySqlGrammar doesn't work with SingleStore.

    What do you think of this? If I get time to work on the tests, I could also add support for HIGHLIGHT.

    Reviewed by fgilio at 2022-06-14 20:22
  • 5. Fix many things in Connection

    Hello @aarondfrancis!

    composer require --dev nunomaduro/larastan
    vendor/bin/phpstan analyze -c vendor/nunomaduro/larastan/extension.neon -l 5 src/
    

    You will discover things like

    diff --git a/src/Connect/Connection.php b/src/Connect/Connection.php
    index 5c3e52e..14007af 100644
    --- a/src/Connect/Connection.php
    +++ b/src/Connect/Connection.php
    @@ -6,18 +6,17 @@
     namespace SingleStore\Laravel\Connect;
    
     use Illuminate\Database\MySqlConnection;
    -use SingleStore\Laravel\Query;
    -use SingleStore\Laravel\QueryGrammar;
    -use SingleStore\Laravel\Schema;
    -use SingleStore\Laravel\SchemaBuilder;
    -use SingleStore\Laravel\SchemaGrammar;
    +use SingleStore\Laravel\Query\Builder as QueryBuilder;
    +use SingleStore\Laravel\Query\Grammar as QueryGrammar;
    +use SingleStore\Laravel\Schema\Builder as SchemaBuilder;
    +use SingleStore\Laravel\Schema\Grammar as SchemaGrammar;
    
     class Connection extends MySqlConnection
     {
         /**
          * Get a schema builder instance for the connection.
          *
    -     * @return SchemaBuilder
    +     * @return \SingleStore\Laravel\Schema\Builder
          */
         public function getSchemaBuilder()
         {
    @@ -25,36 +24,40 @@ class Connection extends MySqlConnection
                 $this->useDefaultSchemaGrammar();
             }
    
    -        return new Schema\Builder($this);
    +        return new SchemaBuilder($this);
         }
    
         /**
          * Get the default query grammar instance.
          *
    -     * @return QueryGrammar
    +     * @return \Illuminate\Database\Grammar
          */
         protected function getDefaultQueryGrammar()
         {
    -        return $this->withTablePrefix(new Query\Grammar);
    +        return $this->withTablePrefix(new QueryGrammar);
         }
    
         /**
          * Get the default schema grammar instance.
          *
    -     * @return SchemaGrammar
    +     * @return \Illuminate\Database\Grammar
          */
         protected function getDefaultSchemaGrammar()
         {
    -        return $this->withTablePrefix(new Schema\Grammar);
    +        return $this->withTablePrefix(new SchemaGrammar);
         }
    
         /**
          * Get a new query builder instance.
    +     *
    +     * @return \SingleStore\Laravel\Query\Builder
          */
         public function query()
         {
    -        return new Query\Builder(
    -            $this, $this->getQueryGrammar(), $this->getPostProcessor()
    +        return new QueryBuilder(
    +            $this,
    +            $this->getQueryGrammar(),
    +            $this->getPostProcessor()
             );
         }
     }
    

    Do you like static analysis?

    Reviewed by szepeviktor at 2022-06-01 15:43
  • 6. php artisan migrate:fresh doesn't work

    As the title states, the command php artisan migrate:fresh doesn't work.

    This also impacts unit tests which use the RefreshDatabase trait.

    The error: SQLSTATE[HY000]: General error: 1295 This command is not supported in the prepared statement protocol yet (SQL: SHOW FULL TABLES WHERE table_type = 'BASE TABLE')

    image
    Reviewed by larskoole at 2022-06-01 08:13
  • 7. Laravel can't find singlestore driver

    First of all, congrats on the package release!

    I've found a bug the following bug. image

    This gets thrown if you use database as your cache driver. In this case it was thrown because the RouteServiceProvider.php uses rate limiting which uses cache which uses the database.

    My guess is that the RouteServiceProvider gets processed before the SingleStoreServiceProvider.

    For the people running into this issue, you can solve it by adding the SingleStoreProvider code to your AppServiceProvider. Note: this is a temporary fix! image

    Reviewed by larskoole at 2022-06-01 06:39
UnionPay driver for the Omnipay PHP payment processing library

Omnipay: UnionPay UnionPay driver for the Omnipay PHP payment processing library Omnipay is a framework agnostic, multi-gateway payment processing lib

May 18, 2022
vPOS Official Wordpres WooCommerce Plugin
vPOS Official Wordpres WooCommerce Plugin

vPOS - WooCommerce The number #1 payment solution in Angola This plugin currently works for the solutions listed below: EMIS GPO (Multicaixa Express)

Jun 13, 2022
Okex API Like the official document interface, Support for arbitrary extension.

It is recommended that you read the official document first Okex docs https://www.okex.com/docs/en Okex Simulation Test API https://www.okex.com/docs/

Jun 8, 2022
This is the official place where Nemesysco's LVA7 and QA7 dockers will be hosted and maintained
This is the official place where Nemesysco's LVA7 and QA7 dockers will be hosted and maintained

LVA-Dockers This is the official place where Nemesysco's LVA7 and QA7 dockers will be hosted and maintained - It is still under construction! We are w

Feb 17, 2022
Phalcon official Forum

Phosphorum 3 Phosphorum is an engine for building flexible, clear and fast forums. You can adapt it to your own needs or improve it if you want. Pleas

Jun 11, 2022
Api.video-wordpress-plugin - The official api.video plugin for WordPress
Api.video-wordpress-plugin - The official api.video plugin for WordPress

api.video WordPress Plugin api.video is the video infrastructure for product builders. Lightning fast video APIs for integrating, scaling, and managin

May 24, 2022
Official OpenMage LTS codebase | Migrate easily from Magento Community Edition in minutes
 Official OpenMage LTS codebase | Migrate easily from Magento Community Edition in minutes

Official OpenMage LTS codebase | Migrate easily from Magento Community Edition in minutes! Download the source code for free or contribute to OpenMage LTS | Security vulnerability patches, bug fixes, performance improvements and more.

Jun 17, 2022
Official Kraken.io Magento Extension

Kraken.io Magento Extension Advanced optimization for your Magento JPEG, PNG, GIF and SVG images Established in 2012, Kraken.io is an industry-leading

Nov 15, 2019
A plugin manager for PocketMine-MP downloads plugin from PocketMine-MP official plugin repository

oh-my-pmmp A plugin manager for PocketMine-MP Getting Started Prerequisites Your server MUST RUN the latest version of PocketMine. Installation From P

Jun 9, 2022
Laravel Blog Package. Easiest way to add a blog to your Laravel website. A package which adds wordpress functionality to your website and is compatible with laravel 8.
Laravel Blog Package. Easiest way to add a blog to your Laravel website. A package which adds wordpress functionality to your website and is compatible with laravel 8.

Laravel Blog Have you worked with Wordpress? Developers call this package wordpress-like laravel blog. Give our package a Star to support us ⭐ ?? Inst

Jul 2, 2022
A Simple Linode SDK built for Laravel with @JustSteveKing laravel-transporter package

linode client A Simple Linode client built for Laravel with @JustSteveKing laravel-transporter package Installation You can install the package via co

Nov 18, 2021
A Laravel Wrapper for the Binance API. Now easily connect and consume the Binance Public & Private API in your Laravel apps without any hassle.
A Laravel Wrapper for the Binance API. Now easily connect and consume the Binance Public & Private API in your Laravel apps without any hassle.

This package provides a Laravel Wrapper for the Binance API and allows you to easily communicate with it. Important Note This package is in early deve

Jun 19, 2022
Laravel Podcast Manager is a complete podcast manager package for Laravel 5.3+ that enables you to manage RSS feeds for your favorite podcasts and listen to the episodes in a seamless UI.
Laravel Podcast Manager is a complete podcast manager package for Laravel 5.3+ that enables you to manage RSS feeds for your favorite podcasts and listen to the episodes in a seamless UI.

laravelpodcast | A Laravel podcast manager package - v0.0.8 Introduction Laravel Podcast Manager is a complete podcast manager package for Laravel 5.3

Oct 3, 2021
Laravel-htaccess - a package for dynamically edit .htaccess in laravel

laravel-htaccess a package for dynamically edit .htaccess in laravel use RedirectHtaccess Facade function for add RedirectHtaccess()->add(); return in

Dec 19, 2021
Laravel & Google Drive Storage - Demo project with Laravel 6.x and earlier

Laravel & Google Drive Storage Demo project with Laravel 8.X Look at the commit history to see each of the steps I have taken to set this up. Set up t

Mar 2, 2022
Empower your business to accept payments globally, earn rewards and invest in crypto with lazerpay laravel sdk in your laravel project.
Empower your business to accept payments globally, earn rewards and invest in crypto with lazerpay laravel sdk in your laravel project.

Lazerpay Laravel Package pipedev/lazerpay is a laravel sdk package that access to laravel api Installation PHP 5.4+ and Composer are required. To get

May 5, 2022
A redacted PHP port of Underscore.js with additional functions and goodies – Available for Composer and Laravel

Underscore.php The PHP manipulation toolbelt First off : Underscore.php is not a PHP port of Underscore.js (well ok I mean it was at first). It's does

Jun 16, 2022
Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services.

Introduction Laravel Cashier provides an expressive, fluent interface to Stripe's subscription billing services. It handles almost all of the boilerpl

Jun 25, 2022
Omnipay for Laravel

Omnipay for Laravel 5/6/7/8 & Lumen Integrates the Omnipay PHP library with Laravel 5 via a ServiceProvider to make Configuring multiple payment tunne

Jun 18, 2022