Skip to content

Commit

Permalink
Fix SQL Server grammar to correctly handle DATETIME columns
Browse files Browse the repository at this point in the history
  • Loading branch information
paulofreitas committed Nov 14, 2017
1 parent 47a543f commit c3425e0
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ protected function asDateTime($value)
// the database connection and use that format to create the Carbon object
// that is returned back out to the developers after we convert it here.
return Carbon::createFromFormat(
$this->getDateFormat(), $value
str_replace('.v', '.u', $this->getDateFormat()), $value
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ public function compileSavepointRollBack($name)
*/
public function getDateFormat()
{
return 'Y-m-d H:i:s.000';
return 'Y-m-d H:i:s.v';
}

/**
Expand Down
76 changes: 76 additions & 0 deletions tests/Database/DatabaseEloquentIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Illuminate\Tests\Database;

use Exception;
use ReflectionObject;
use PHPUnit\Framework\TestCase;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;
Expand Down Expand Up @@ -1138,6 +1139,76 @@ public function testFreshMethodOnCollection()
$this->assertEquals($users->map->fresh(), $users->fresh());
}

public function testTimestampsUsingDefaultDateFormat()
{
$model = new EloquentTestUser;
$model->setDateFormat('Y-m-d H:i:s'); // Default MySQL/PostgreSQL/SQLite date format
$model->setRawAttributes([
'created_at' => '2017-11-14 08:23:19',
]);

$this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at')));
$this->assertEquals('2017-11-14 08:23:19', $model->fromDateTime($model->getAttribute('created_at')));
}

public function testTimestampsUsingDefaultSqlServerDateFormat()
{
$model = new EloquentTestUser;
$model->setDateFormat('Y-m-d H:i:s.v'); // Default SQL Server date format
$model->setRawAttributes([
'created_at' => '2017-11-14 08:23:19.000',
'updated_at' => '2017-11-14 08:23:19.734',
]);

$this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at')));
$this->assertEquals('2017-11-14 08:23:19.734000', $this->getRawDateTimeString($model->getAttribute('updated_at')));
$this->assertEquals('2017-11-14 08:23:19.000', $model->fromDateTime($model->getAttribute('created_at')));
$this->assertEquals('2017-11-14 08:23:19.734', $model->fromDateTime($model->getAttribute('updated_at')));
}

public function testTimestampsUsingCustomDateFormat()
{
// Simulating using custom precisions with timestamps(4)
$model = new EloquentTestUser;
$model->setDateFormat('Y-m-d H:i:s.u'); // Custom date format
$model->setRawAttributes([
'created_at' => '2017-11-14 08:23:19.0000',
'updated_at' => '2017-11-14 08:23:19.7348',
]);

$this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at')));
$this->assertEquals('2017-11-14 08:23:19.734800', $this->getRawDateTimeString($model->getAttribute('updated_at')));
// Note: when storing databases would truncate the value to the given precision
$this->assertEquals('2017-11-14 08:23:19.000000', $model->fromDateTime($model->getAttribute('created_at')));
$this->assertEquals('2017-11-14 08:23:19.734800', $model->fromDateTime($model->getAttribute('updated_at')));
}

public function testTimestampsUsingOldSqlServerDateFormat()
{
$model = new EloquentTestUser;
$model->setDateFormat('Y-m-d H:i:s.000'); // Old SQL Server date format
$model->setRawAttributes([
'created_at' => '2017-11-14 08:23:19.000',
]);

$this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at')));
$this->assertEquals('2017-11-14 08:23:19.000', $model->fromDateTime($model->getAttribute('created_at')));
}

/**
* @expectedException \InvalidArgumentException
*/
public function testTimestampsUsingOldSqlServerDateFormatFailInEdgeCases()
{
$model = new EloquentTestUser;
$model->setDateFormat('Y-m-d H:i:s.000'); // Old SQL Server date format
$model->setRawAttributes([
'updated_at' => '2017-11-14 08:23:19.734',
]);

$attribute = $model->fromDateTime($model->getAttribute('updated_at'));
}

/**
* Helpers...
*/
Expand All @@ -1161,6 +1232,11 @@ protected function schema($connection = 'default')
{
return $this->connection($connection)->getSchemaBuilder();
}

protected function getRawDateTimeString($object)
{
return (new ReflectionObject($object))->getProperty('date')->getValue($object);
}
}

/**
Expand Down

0 comments on commit c3425e0

Please sign in to comment.