• Stars
    star
    544
  • Rank 78,698 (Top 2 %)
  • Language
    PHP
  • License
    MIT License
  • Created over 3 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A MySQL engine written in pure PHP

PHP MySQL Engine

PHP MySQL Engine is a library for PHP that allows you to test database-driven applications with an in-memory simulation of MySQL 5.6. This project extends the PDO class and allows you to call common PDO MySQL methods. It supports a wide variety of queries, and some PDO-specific functionality like transactions and different fetch modes.

PHP MySQL Engine is based on Slack's Hack SQL Fake created by Scott Sandler.

You can read an article about this tool here.

Motivation

Currently there are two ways to test code that reads and writes to a database:

  • Mock SQL query execution
    Mocks require an explicit list of queries that are expected to run and results to return. This leads to significant manual work setting up expectations, and tests which are fragile and must be updated even on benign changes to the code or queries. It also means the data access layer is not unit tested.

  • Use an actual database
    It might make sense to test with a separate database instance – this is what we have done in the past at Vimeo. But databases like MySQL are designed to be filled with lots of long-lasting data, whereas unit tests write small amounts of very short-lived data. This means that extra care has to be taken to make sure that test databases are truncated between tests, which creates a performance issue.

PHP MySQL Engine takes a different approach - it parses and executes SELECT, INSERT, UPDATE, and DELETE queries against an in-memory "database" stored in PHP arrays. As long as the amount of data used for testing is small, this solves the problems mentioned above.

SQL Syntax Supported

This library supports a wide variety of query syntax, including:

  • FROM, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT clauses supported as appropriate for each query type
  • JOIN queries with all join types
  • multi-queries such as subqueries, UNION, UNION ALL, INTERSECT, EXCEPT
  • complex expressions such as CASE, BETWEEN, and row comparators (1, 2, 3) < (4, 5, 6)
  • all basic operators implemented with operator precedence
  • column aliases, cross-database queries
  • INSERT ... ON DUPLICATE KEY UPDATE
  • A variety of SQL functions such as COUNT(), NULLIF(), COALESCE(), CONCAT_WS() and many others
  • Temporary variables like @previous_name := user.name
  • Validating parser: the query parser will throw exceptions on most invalid SQL Queries, helping protect your production environment from accidental SQL syntax errors

Unsupported MySQL features

This engine does not support MySQL Stored objects, which precludes the testing of stored procedures, triggers and views.

Caveat Emptor

Unlike Psalm, this package is not designed with a wide audience in mind. For a project to really benefit from this library it should already have a large number of tests that require a database connection to complete, and the project maintainers must understand the tradeoffs associated with using an unofficial MySQL implementation in their test suite.

Known issues

Result types when not emulating prepares

By default the engine returns all data formatted as a string. If $pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false) is called, the engine will instead infer column types (for example, SUM(some_int_column) will be given an int type). In some cases php-mysql-engine may do a better job of inferring correct column types than actual MySQL, which defaults to string when it can’t work out a column type. If you do strict type checks on the results you may see small discrepancies.

Installation

composer require --dev vimeo/php-mysql-engine

Usage

PHP MySQL Engine works by providing a subclass of PDO.

You can instantiate the subclass as you would PDO, and use dependency injection or similar to provide that instance to your application code.

// use a class specific to your current PHP version (APIs changed in major versions)
$pdo = new \Vimeo\MysqlEngine\Php8\FakePdo($dsn, $user, $password);
// currently supported attributes
$pdo->setAttribute(\PDO::ATTR_CASE, \PDO::CASE_LOWER);
$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);

The rest of your code can operate as normal, using the database in the same way it is used in production.

Why doesn't it support X?

This library aims to support everything its users use in MySQL, rather than every possibly feature MySQL offers. We welcome pull requests to add support for new syntax, sql functions, data types, bug fixes, and other features.

Why doesn’t this project have an issue tracker?

Maintaining open-source projects is hard work, and I don't want to make more work for me or my colleagues. Use this project very much use at your own risk.

If you want to fork the project with an issue tracker, feel free!

Contributing

If you want to create a PR, please make sure it passes unit tests:

vendor/bin/phpunit

and also Psalm's checks

vendor/bin/psalm

Thanks!

More Repositories

1

psalm

A static analysis tool for finding errors in PHP applications
PHP
5,440
star
2

player.js

Interact with and control an embedded Vimeo Player.
JavaScript
1,413
star
3

graph-explorer

A graphite dashboard powered by structured metrics
Python
1,060
star
4

player-api

Examples for our JavaScript and ActionScript player APIs.
450
star
5

vimeo.php

Official PHP library for the Vimeo API.
PHP
445
star
6

laravel

A Vimeo bridge for Laravel
PHP
384
star
7

stag-java

Speedy Type Adapter Generation
Java
351
star
8

VIMVideoPlayer

Deprecated: Please use [PlayerKit]( https://github.com/vimeo/PlayerKit) instead.
Objective-C
281
star
9

vimeo.js

Official Node.js library for the Vimeo API.
JavaScript
264
star
10

vimeo-oembed-examples

Some examples of how to use our oEmbed endpoint
HTML
237
star
11

vimeo.py

Official Python library for the Vimeo API.
Python
210
star
12

vimeo-unity-sdk

Easily stream your Vimeo videos into Unity or record and publish out to Vimeo.
C#
208
star
13

graphite-influxdb

An influxdb backend for Graphite-web and graphite-api
Python
198
star
14

vimeo-php-lib

Our official PHP library for the Advanced API.
PHP
180
star
15

tailgate

Tailgate is a nodejs app to pipe `tail -F` into websockets. It's a very simple way to have real-time access to your logs.
JavaScript
164
star
16

ABLincoln

A library for online experiments.
PHP
154
star
17

PlayerKit

Swift
154
star
18

vimeo-networking-java

The Vimeo Java (Android) SDK
Kotlin
122
star
19

py-money

Money class for Python 3
Python
121
star
20

vimeo-threejs-player

A plugin for streaming video from Vimeo to WebGL/VR/AR apps
JavaScript
88
star
21

tattletale.js

A utility to send console logs over XHR for server-side processing.
JavaScript
87
star
22

VimeoNetworking

The Vimeo API iOS SDK
Swift
83
star
23

vimeo-depth-player

A WebVR volumetric video renderer that uses color-depth based videos hosted on Vimeo.
JavaScript
83
star
24

aframe-vimeo-component

Stream Vimeo videos into WebVR.
JavaScript
81
star
25

simple-black-box

A simple black-box behavior testing framework
Shell
68
star
26

pentagon

Vault <-> Kubernetes Secrets
Go
59
star
27

VimeoUpload

The Vimeo iOS Upload SDK
Swift
59
star
28

whisper-to-influxdb

migrate (import) graphite data from whisper to influxdb
Go
58
star
29

smoketcp

Smokeping like tcp connectivity tester, reports to statsd. written in Golang
Go
58
star
30

VIMNetworking

The Vimeo iOS SDK
Objective-C
58
star
31

libvmod-boltsort

A fast Varnish module for sorting query string parameters.
C
58
star
32

vimeo-depth-viewer

OpenGL application for viewing depth and color video streams from Intel RealSense cameras
C++
52
star
33

iris

Vimeo Design System
TypeScript
50
star
34

carbon-tagger

native tag-based metrics for graphite/carbon
Go
50
star
35

go-util

Small reusable Go functions.
Go
44
star
36

Blueprint

aka How We Collaborate
41
star
37

graphite-api-influxdb-docker

docker image with graphite-api and graphite-influxdb
Shell
39
star
38

go-magic

Go Bindings for libmagic and an idiomatic API for getting a file's MIME type.
Go
39
star
39

rollup-plugin-bundle-size

A rollup plugin to show the size of the generated bundle(s).
JavaScript
29
star
40

vimeo-maxmsp

Play and manipulate Vimeo videos in Max/MSP and Jitter
Max
24
star
41

openapi

An OpenAPI specification for the Vimeo API.
17
star
42

VIMDeeplink

Simple Objc and Swift wrappers around the Vimeo iOS deeplink API
Swift
17
star
43

puppet-diamond

diamond module for puppet
Puppet
15
star
44

nagios-cloudwatch-plugin

AWS CloudWatch check Nagios plugin
Python
14
star
45

elevator

Validate and patch AV1 levels
Rust
12
star
46

puppet-statsd

statsd module for puppet
Puppet
11
star
47

VIMUpload

This library has been deprecated, use VimeoUpload instead
Objective-C
11
star
48

go-hammer

Go
10
star
49

VIMObjectMapper

An automatic JSON to model object converter
Objective-C
10
star
50

babel-plugin-transform-i18n

A Babel transform plugin to replace strings with their translations.
JavaScript
10
star
51

dials

Dials is an extensible configuration package for Go.
Go
9
star
52

go-clocks

A convenient package providing a Clock abstraction in Go
Go
9
star
53

go-taglog

Based on, and compatible with, the Go standard log package, but also provides additional functionality and features such as tagging.
Go
8
star
54

leaderelection

Go
8
star
55

ios-labs-staffpicks

An iOS Labs sample project
Swift
7
star
56

zendesk-ticket-history

JavaScript
7
star
57

grouplogger

Go
6
star
58

netstorage

go client for the new Akamai Netstorage http api
Go
6
star
59

caps

Go package to read/write popular video caption formats(mostly a port of pycaption)
Go
6
star
60

Uniform

Swift
6
star
61

alog

Another Go Logging Package
Go
5
star
62

vimeo-live-player-examples

Example application for using Vimeo Live M3U8 links with third-party players
HTML
5
star
63

graph-explorer-docker

Shell
5
star
64

eslint-config-player

ESLint config for all player team projects.
JavaScript
5
star
65

go-iccjpeg

A small utility package to extract ICC profiles from JPEGs.
Go
4
star
66

graphite-go

Go
4
star
67

go-retry

A small package for doing comprehensive retries.
Go
4
star
68

go-imgparse

A small go library to efficiently parse the resolution of various image format streams.
Go
4
star
69

vimeo-deeplink-android

A helper library to deep link into the official Vimeo Android App
Java
3
star
70

payment-gateway-logger

PHP
3
star
71

av1stats

An AV1 stream analysis CLI tool
Rust
3
star
72

omnipay-bluesnap

BlueSnap driver for the Omnipay PHP payment processing library
PHP
3
star
73

genepool

A golang package for building generic workpools in a standardized way
Go
2
star
74

omnipay-vindicia

Vindicia driver for the Omnipay PHP payment processing library
PHP
2
star
75

VimeoCommon

1
star
76

k8swatcher

Convenient watching interface for Kubernetes.
Go
1
star
77

policy

1
star