Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
051816e
update phpunit
shmax Aug 20, 2023
060c800
update phpunit.dist.xml, fix require
shmax Aug 20, 2023
e770356
let's try setting up actions
shmax Aug 20, 2023
741c9e1
move to Monolog
shmax Aug 25, 2023
4a51343
add file
shmax Aug 25, 2023
5183286
fix warnings
shmax Aug 25, 2023
47dfaec
fix lots of tests
shmax Aug 26, 2023
608e942
maybe fix relationship get
shmax Aug 26, 2023
b046575
fix properly
shmax Aug 26, 2023
d1215bd
fix more tests
shmax Aug 26, 2023
6cd00d7
fix even more tests
shmax Aug 26, 2023
0e1d4cd
revert port
shmax Aug 26, 2023
f69997a
fix tests
shmax Aug 26, 2023
265f39d
use native methods
shmax Aug 26, 2023
fcbdce0
simplify
shmax Aug 26, 2023
eacc056
simplify
shmax Aug 26, 2023
6e9c843
simplify, cleanup
shmax Aug 26, 2023
955dd2d
fix warnings
shmax Aug 27, 2023
d4d1fb6
fix warnings
shmax Aug 27, 2023
60419c9
update markup
shmax Aug 27, 2023
417d8b2
Merge remote-tracking branch 'origin/master' into fix-tests
shmax Aug 27, 2023
4bb2210
fix markTestSkipped
shmax Aug 27, 2023
6df9228
use mysql in CI
shmax Aug 27, 2023
957cdde
fix indent
shmax Aug 27, 2023
7108e3c
try using docker
shmax Aug 27, 2023
b259485
try again
shmax Aug 27, 2023
ebeb004
move block
shmax Aug 27, 2023
df70261
remove member
shmax Aug 27, 2023
9b16d16
try something
shmax Aug 27, 2023
700d7e5
try something
shmax Aug 27, 2023
88947f7
revert
shmax Aug 27, 2023
d25708e
try something
shmax Aug 27, 2023
3b6ae4a
revert
shmax Aug 27, 2023
fa969b5
try using dockerhub
shmax Aug 27, 2023
09fb9dc
setup sqlite
shmax Aug 27, 2023
a578c2c
set permissions
shmax Aug 27, 2023
0cc16c2
set permissions
shmax Aug 27, 2023
80e5a29
set permissions
shmax Aug 27, 2023
8d82a76
fix path
shmax Aug 27, 2023
67064a0
try wait flag
shmax Aug 28, 2023
378a1dc
add timeout
shmax Aug 28, 2023
0a23329
try sleeping
shmax Aug 28, 2023
b938b28
try --build
shmax Aug 28, 2023
0400f24
try memcache
shmax Aug 28, 2023
1a8ae40
try memcached
shmax Aug 28, 2023
8928821
fix sqlite
shmax Aug 30, 2023
7e8ff61
debugging
shmax Aug 30, 2023
d9a326c
debugging
shmax Aug 30, 2023
ebb7957
debugging
shmax Aug 30, 2023
ed33ff7
debugging
shmax Aug 30, 2023
07376a7
debugging
shmax Aug 30, 2023
9c65528
debugging
shmax Aug 30, 2023
9aa2b66
debugging
shmax Aug 30, 2023
d82fec8
debugging
shmax Aug 30, 2023
d2e3c22
debugging
shmax Aug 30, 2023
6281b4d
debugging
shmax Aug 30, 2023
5838908
debugging
shmax Aug 30, 2023
6d9c00a
debugging
shmax Aug 30, 2023
b69d75d
debugging
shmax Aug 30, 2023
86298a2
debugging
shmax Aug 30, 2023
bb906f6
debugging
shmax Aug 30, 2023
4005f04
debugging
shmax Aug 30, 2023
9aa46ab
debugging
shmax Aug 30, 2023
1452ae7
debugging
shmax Aug 30, 2023
6d42aa7
try focusing on sqliteadapter test
shmax Aug 30, 2023
4528bb6
disable code-coverage for now
shmax Aug 30, 2023
301f405
try mysql
shmax Aug 30, 2023
a26e5b2
check drivers
shmax Aug 30, 2023
ae53bda
trying something
shmax Aug 30, 2023
4d86a5a
trying something
shmax Aug 30, 2023
891d4d7
try verbose
shmax Aug 30, 2023
87c5e75
try verbose
shmax Aug 30, 2023
cf44888
try using config
shmax Aug 30, 2023
a79c556
fix command
shmax Aug 30, 2023
520ee9e
try testdox
shmax Aug 30, 2023
6eab307
output skipped messages
shmax Aug 30, 2023
1c8680c
verify mysql
shmax Aug 30, 2023
1800f69
use host and port
shmax Aug 30, 2023
410f73b
use mysql service
shmax Aug 30, 2023
06cd27c
remove testdox
shmax Aug 30, 2023
8d1522f
fix indext
shmax Aug 30, 2023
fecc014
set up postgresql
shmax Aug 30, 2023
ce31310
set up postgresql
shmax Aug 30, 2023
26855ab
add memcached
shmax Aug 30, 2023
6e8b1b8
test cache
shmax Aug 30, 2023
715f4bf
all tests
shmax Aug 30, 2023
3fcd546
simplify static connection shit
shmax Aug 30, 2023
8c95e22
cache connection name
shmax Aug 30, 2023
e31cb9c
use connection_name
shmax Aug 30, 2023
b1622f7
set up coverage
shmax Aug 30, 2023
e65ad20
fix dir
shmax Aug 30, 2023
2dacf63
fix coverage
shmax Aug 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Test
permissions:
contents: write
on:
pull_request:
push:
branches:
- master

jobs:
phpunit:
name: PHPUnit
runs-on: ubuntu-20.04
services:
memcached:
image: memcached:1.6
ports:
- 11211:11211
options: --name memcached-container
mysql:
image: mysql:5.7
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: test
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
postgres:
image: postgres:13
env:
POSTGRES_DB: test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5

strategy:
fail-fast: false
matrix:
php-version:
- 8.1
- 8.2

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Install PHP
uses: shivammathur/setup-php@v2
with:
coverage: pcov
ini-values: zend.assertions=1, assert.exception=1
php-version: ${{ matrix.php-version }}
extensions: memcached
tools: cs2pr

- name: Check drivers
run: php drivers.php

- name: Install dependencies with Composer
uses: ramsey/composer-install@v2

- name: Create and set permissions on SQLite Database
run: |
touch test.db
echo $USER:$USER
sudo chown $USER:$USER test.db
chmod 777 test.db

# Verify SQLite installation and permissions
- name: Verify SQLite setup
run: |
sqlite3 --version
ls -la test.db
sqlite3 test.db "CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, name TEXT);"
ls -la test.db

- name: Verify MySQL
run: |
echo "MySQL Connection String: mysql://test:test@localhost:3306/test"

- name: Verify PostgreSQL
run: |
echo "PostgreSQL Connection String: postgres://test:test@localhost:5432/test"

- name: Run PHPUnit
run: |
vendor/bin/phpunit -c phpunit.xml.dist

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*.log
*.db
*.swp
.phpunit.cache
vendor/*
output/*
composer.lock
Expand All @@ -13,3 +14,4 @@ phpunit.xml
.php_cs
docs/api
.phpunit.result.cache
.stan-cache
1 change: 1 addition & 0 deletions ActiveRecord.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
require __DIR__ . '/lib/DateTime.php';
require __DIR__ . '/lib/Model.php';
require __DIR__ . '/lib/Table.php';
require __DIR__ . '/lib/Relationship.php';
require __DIR__ . '/lib/ConnectionManager.php';
require __DIR__ . '/lib/Connection.php';
require __DIR__ . '/lib/Serialization.php';
Expand Down
31 changes: 30 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,36 @@ tests, pass the `--verbose` flag to PHPUnit:
vendor/bin/phpunit --verbose
```

Some common steps for fixing skipped tests are to:
For Docker users, a docker-compose.yml has been provided in the project root that will provide:
- mysql
- postgres
- memcached

Simply run:
```shell
docker-composer up -d
```

Then, the necessary services will be available and the tests should pass (although you may need to install PHP memcache extensions in a separate step, see below ).

When you're done, you can take it down with:
```sh
docker-compose down
```

#### Installing memcache on Windows
If you're a Windows user, finding the correct memcache drivers can be a bit tricky, as the PECL repo seems to be in disrepair. You can find them here:

https://github.com/nono303/PHP-memcache-dll/tree/master

Download the .dll that matches your version of PHP, install it into your /ext dir, and add this line to your php.ini:
```ini
extension=memcache
```


#### Alternate setup
If Docker is not available to you, or you would simply not use it, you will have to do your best to install the various services on your own.

* Install `memcached` and the PHP memcached extension (e.g., `brew install php56-memcache memcached` on macOS)
* Install the PDO drivers for PostgreSQL (e.g., `brew install php56-pdo-pgsql` on macOS)
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# PHP ActiveRecord

[![Build Status](https://travis-ci.org/jpfuentes2/php-activerecord.png?branch=master)](https://travis-ci.org/php-activerecord/activerecord)
[![Test](https://github.com/php-activerecord/activerecord/actions/workflows/test.yml/badge.svg)](https://github.com/php-activerecord/activerecord/actions/workflows/test.yml)
[![Coverage Status](https://codecov.io/gh/shmax/graphql-php-validation-toolkit/branch/master/graph/badge.svg)](https://codecov.io/gh/shmax/graphql-php-validation-toolkit/branch/master)

**We encourage pull requests, and issues will be dealt with thoroughly and in a timely manner.**

Expand Down
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@
"php": ">=8.1.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5.21",
"pear/pear_exception": "1.0",
"phpunit/phpunit": "^10",
"friendsofphp/php-cs-fixer": "^2.1",
"pear/log": "~1.13"
"monolog/monolog": "^3.4"
},
"autoload": {
"files": [ "ActiveRecord.php" ]
},
"scripts": {
"style-check" : "php vendor/bin/php-cs-fixer fix --dry-run --verbose --diff",
"style-fix" : "php vendor/bin/php-cs-fixer fix --verbose"
"style-fix" : "php vendor/bin/php-cs-fixer fix --verbose",
"test": "phpunit"
}
}
28 changes: 28 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
version: '3.8'
services:
mysql:
image: mysql:latest
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: test
ports:
- "3306:3306"

postgres:
image: postgres:latest
environment:
POSTGRES_DB: test
POSTGRES_USER: test
POSTGRES_PASSWORD: test
ports:
- "5432:5432"

memcached:
image: memcached:latest
ports:
- "11211:11211"
environment:
- MEMCACHED_MEMORY_LIMIT=64
- MEMCACHED_MAX_CONNECTIONS=1024
3 changes: 3 additions & 0 deletions drivers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<?php

var_export(PDO::getAvailableDrivers());
5 changes: 3 additions & 2 deletions lib/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace ActiveRecord;

use Closure;
use Psr\Log\LoggerInterface;

/**
* Manages configuration options for ActiveRecord.
Expand Down Expand Up @@ -242,9 +243,9 @@ public function set_logging($bool)
*
* @param object $logger
*
* @throws ConfigException if Logger objecct does not implement public log()
* @throws ConfigException if Logger object does not implement public log()
*/
public function set_logger($logger)
public function set_logger(LoggerInterface $logger)
{
$klass = Reflections::instance()->add($logger)->get($logger);

Expand Down
23 changes: 13 additions & 10 deletions lib/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ abstract class Connection
*/
private $logging = false;
/**
* Contains a Logger object that must impelement a log() method.
* Contains a Logger object that must implement a log() method.
*
* @var object
*/
Expand All @@ -71,7 +71,7 @@ abstract class Connection
*
* @var string
*/
public static $datetime_format = 'Y-m-d H:i:s T';
public static $datetime_format = 'Y-m-d H:i:s';
/**
* Default PDO options to set for each connection.
*
Expand All @@ -98,7 +98,7 @@ abstract class Connection
/**
* Retrieve a database connection.
*
* @param string $connection_string_or_connection_name A database connection string (ex. mysql://user:pass@host[:port]/dbname)
* @param string|null $connection_string_or_connection_name A database connection string (ex. mysql://user:pass@host[:port]/dbname)
* Everything after the protocol:// part is specific to the connection adapter.
* OR
* A connection name that is set in ActiveRecord\Config
Expand All @@ -108,11 +108,11 @@ abstract class Connection
*
* @see parse_connection_url
*/
public static function instance($connection_string_or_connection_name=null)
public static function instance(string $connection_string_or_connection_name=null)
{
$config = Config::instance();

if (false === strpos($connection_string_or_connection_name, '://')) {
if (!str_contains($connection_string_or_connection_name ?? '', '://')) {
$connection_string = $connection_string_or_connection_name ?
$config->get_connection($connection_string_or_connection_name) :
$config->get_default_connection_string();
Expand Down Expand Up @@ -272,7 +272,8 @@ protected function __construct($info)
$host = "unix_socket=$info->host";
}

$this->connection = new PDO("$info->protocol:$host;dbname=$info->db", $info->user, $info->pass, static::$PDO_OPTIONS);
$dsn = "$info->protocol:$host;dbname=$info->db";
$this->connection = new PDO($dsn, $info->user, $info->pass, static::$PDO_OPTIONS);
} catch (PDOException $e) {
throw new DatabaseException($e);
}
Expand Down Expand Up @@ -333,9 +334,9 @@ public function insert_id($sequence=null)
public function query($sql, &$values=[])
{
if ($this->logging) {
$this->logger->log($sql);
$this->logger->info($sql);
if ($values) {
$this->logger->log($values);
$this->logger->info(var_export($values, true));
}
}

Expand All @@ -352,11 +353,13 @@ public function query($sql, &$values=[])
$sth->setFetchMode(PDO::FETCH_ASSOC);

try {
$msg = "couldn't execute query on " . get_class($this) . ". ";
$msg .= "user: " .getenv('USER');
if (!$sth->execute($values)) {
throw new DatabaseException($this);
throw new DatabaseException($msg);
}
} catch (PDOException $e) {
throw new DatabaseException($e);
throw new DatabaseException($msg . ": " . $e->getMessage());
}

return $sth;
Expand Down
2 changes: 1 addition & 1 deletion lib/ConnectionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ConnectionManager extends Singleton
public static function get_connection($name=null)
{
$config = Config::instance();
$name = $name ? $name : $config->get_default_connection();
$name = $name ?? $config->get_default_connection();

if (!isset(self::$connections[$name]) || !self::$connections[$name]->connection) {
self::$connections[$name] = Connection::instance($config->get_connection($name));
Expand Down
13 changes: 7 additions & 6 deletions lib/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,6 @@ public function &read_attribute($name)
// this may be first access to the relationship so check Table
if (($relationship = $table->get_relationship($name))) {
$this->__relationships[$name] = $relationship->load($this);

return $this->__relationships[$name];
}

Expand Down Expand Up @@ -735,12 +734,14 @@ public static function table_name()
*/
private function is_delegated($name, &$delegate)
{
if ('' != $delegate['prefix']) {
$name = substr($name, strlen($delegate['prefix'])+1);
}
if (is_array($delegate)) {
if ('' != $delegate['prefix']) {
$name = substr($name, strlen($delegate['prefix'])+1);
}

if (is_array($delegate) && in_array($name, $delegate['delegate'])) {
return $name;
if(in_array($name, $delegate['delegate'])) {
return $name;
}
}

return null;
Expand Down
6 changes: 2 additions & 4 deletions lib/Relationship.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ protected function set_class_name($class_name)

protected function create_conditions_from_keys(Model $model, $condition_keys=[], $value_keys=[])
{
$condition_string = implode('_and_', $condition_keys);
$condition_string = implode('_and_', $condition_keys ?? []);
$condition_values = array_values($model->get_values_for($value_keys));

// return null if all the foreign key values are null so that we don't try to do a query like "id is null"
Expand Down Expand Up @@ -506,7 +506,7 @@ public function load(Model $model)
$this->set_keys(get_class($model));

// since through relationships depend on other relationships we can't do
// this initiailization in the constructor since the other relationship
// this initialization in the constructor since the other relationship
// may not have been created yet and we only want this to run once
if (!isset($this->initialized)) {
if ($this->through) {
Expand Down Expand Up @@ -706,8 +706,6 @@ public function load(Model $model)
*/
class BelongsTo extends AbstractRelationship
{
private $primary_key;

public function __construct($options=[])
{
parent::__construct($options);
Expand Down
4 changes: 2 additions & 2 deletions lib/SQLBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ public function delete()
/**
* Reverses an order clause.
*/
public static function reverse_order($order)
public static function reverse_order($order = '')
{
if (!trim($order)) {
if (!trim($order ?? '')) {
return $order;
}

Expand Down
Loading