User tests: Successful: Unsuccessful:
Based on the problem of saving data with different types.
[4.0] Error when saving an object in JTable->save()
I've done a great job of implementing a typizations sub-framework for a Table
class.
The problem is that before you could not create properties of the Table
class with different types, you were forced to create properties without types. You had to use the default types.
But now in the modern world, you can use the Table
class with fully typed properties. You don't need to worry that a DateTime property will cause an error. The DateTime property and other properties will be automatically converted to the database type before being saved. When the Table
is loaded, all properties will be automatically converted to objects, such as a DateTime object.
Now, when programming, you will focus only on business logic.
.
At the same time, the updated Table
class supports the previous usage scenarios. You don't need to redo the programs you've already created.
.
Bonus: The update made it possible to stop using the methods of the deprecated CMSObject class. The new Table
class still inherits the CMSObject class, but now no method is used from this parent class.
.
The new Table
class will allow you to discard the parent CMSObject class without loss in the future.
I checked this class, it does not violate the CMS in any way. But I still think that the code requires minor optimization.
.
I ask you not to ban my work, but to help solve the problem of complete typizations of classes, since technologies do not stand still.
In the modern world, typizations is a basic feature for frameworks.
Status | New | ⇒ | Pending |
Category | ⇒ | Libraries |
Labels |
Added:
?
|
Before going any further with this I would check to make sure it is not too late for 4.0
If it is too late (and I expect it is too late) is it suitable for inclusion in 4.1 or are the changes in this PR breaking.
It's too late for 4.0 and I'm pretty sure it has a b/c and can't go into 4.x beside that there are many errors and wrong assumptions in this code.
@korenevskiy Please fix code style errors reported here: https://ci.joomla.org/joomla/joomla-cms/45273/1/6 .
Question: Have you tested if your code also works with PostgreSQL?
I didn't check it. But thanks for the heads-up.
The class has a type mapping array.
I will add the missing PostgreSQL types to this array.
But I want to note the following. The Table class does not violate the basic usage. So the legacy compatibility is there. In legacy mode, the class must support. In the new mode, I will add type mapping to the array
This PR and the discussion #33840 behind it make the false assumption that when you save a table and haven't included a column, the default value shall be used. This shows a fundamental misunderstanding of the concept behind default values in databases.
The default values shall only be used for INSERT statements when a column is not given in that statement. It shall not be used for UPDATE because in this case the old value shall not be changed.
The basic idea behind default values is that the database cares for it and not the client, and normally any SQL client doesn't even need to know about default values, that's the idea behind it.
So if a client software is not made for showing details about data structures, like phpMyAdmin, but only for showing data, this client does not need to have any information about default values.
This PR here violates this fundamental idea behind default values.
The default values shall only be used for INSERT statements when a column is not given in that statement. It shall not be used for UPDATE because in this case the old value shall not be changed.
The concept of the class is as follows. So that the developer can use this class without thinking at all about the default values.
.
I'd rather show you an example
class Product extends Table{
public JDate $datetime2;
public ?JDate $datetime2;
}
The Table class will create an object for the $datetime1
property, since this property cannot be uninitialized.
However, $datetime2
will be NULL. Which will be replaced by the default value in the database.
But this is the developer's choice, the developer can choose to substitute default values at the DB level or at the PHP level.
Why so, yes, because the new features do not contradict your remark.
Without new features where default values are used at the PHP level, if you remove this feature, then the script is forced to cause an error. since the property type cannot be uninitialized.
A non-NULL property cannot be uninitialized, either an error or a new function.
.
On the other hand, this feature can be presented by analogy with LINQ in C#. When the developer does not think about what will happen after saving, then to remember the data that was assigned to the database. The developer immediately works with the data.
Let me remind you if you DO NOT add this feature, then you need to create an error exception.
Thus, all the new features that would be thanks to typizations. We will use not half-strength typizations.
@richard67
Please tell me, what is the meaning of the JTable->reset()
method?
If this method resets the properties. Then why not reset the properties to their default values?
@richard67
I added PostgreSQL types to the class.
But even in PostgreSQL, there are types like Point or Line.
It's hard to guess what type to convert these types to. But the new class can handle it. If the property name has the interface "TablePropertyInterface", then the new table class uses the property type of the table class to create an object, and then passes the value of Point or Line to the constructor of this object. This enables automatic conversion of types on the fly to a compatible format.
I hope this argument will be true for you @richard67
class Product extends Table{
public int $countProducts;
}
$prod = new Product;
$prod->reset();
What do we get for $countProducts
?
$countProducts == 0 ?
Why?, if the default value in the database is 8.
When calling the method $prod->store() ;
The data in the table is stored 0. But in the database, the default value is 8.
It's not fair.
THE NEW Table CLASS SOLVES THIS PROBLEM.
After resetting, the data will still be saved as the default values for the table when saved.
Is that a bad thing?
A table class that assigns default values only in one case.
When a property was set to a type, but was not initialized.
Let me remind you that the default values are not set in all cases, but only when the property has a type and is not initialized.
Which means that in the old version this behavior was not handled at all, and in the new version of the table it now works.
@brianteeman
The code contains methods
ReflectionProperty::getType();
Why do I use it? The fact is that it is not possible to use similar other functions.
Previously, the class used the get_object_vars()
function.
But the fact is that this function does not allow you to detect the type before initializing the properties of the object.
For a class whose properties do not have typed modifiers, the get_object_vars()
function is sufficient. But to determine the types of properties that have not yet been initialized, you need this method.
ReflectionProperty::getType();
There is no other solution.
.
So my brilliant suggestion is not applicable for Joomla 4 compatible with PHP 7.2.
The community needs to think about changing the minimum version of Joomla to PHP 7.4.
Or typization the properties of the Table class is not applicable at all.
@HLeithner answered my question so time must be spent concentrating on releasing 4.0 and anything else can wait
@HLeithner answered my question so time must be spent concentrating on releasing 4.0 and anything else can wait
We can change the requirements for Joomla4.1?
I will move the PR to Joomla4.1.
I looked for the Joomla4.1 requirements of PHP 7.2.25.
New Table even for J4. 1 will not pass the tests.
To which version can we raise the requirements of PHP 7.4 or 8.0?
We try hard to follow our b/c policy maybe you want to read the development strategy https://developer.joomla.org/news/586-joomla-development-strategy.html#backward_compatibility part of it is that we use semver which doesn't allow to make breaking changes in minor versions.
That's the b/c part but there are other things wrong in the pr. I don't want to discuss now because 4.0 is more important for now.
@HLeithner Sorry.
thank you very much for your comment. PR does not violate backward compatibility. PR adds processing for typed properties. For non-typed properties, nothing changes. . Of course, there are mistakes that take time. . I want to denote. Even if my PR is bad and we delete it, then in any case, any support for typization in the Table class will require PHP 7.4. And according to B/C, there will be no typization in the tables at all until Joomla5.
I now still ruled the table. I deleted the code I wrote in several places, and optimized some things.
@brianteeman @richard67
Can we create another new Table class and place it next to the previous one? We will call it by another name, for example: TableTypes
.
This way we will not violate minor version compatibility. We will be able to test this feature and find out the pitfalls when converting types.
It will not go into 4.0 anyway because of feature freeze, and I have to focus on getting 4.0 ready and don't have the time for this thing here.
Labels |
Added:
?
Removed: ? |
I have recreated the PR in the next version of Joomla 4.1
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2021-08-20 07:45:00 |
Closed_By | ⇒ | korenevskiy | |
Labels |
Added:
?
Removed: ? |
@korenevskiy Does it replace this PR? If so, please close.
@korenevskiy Does it replace this PR? If so, please close.
OK, I've already closed it.
@korenevskiy Please fix code style errors reported here: https://ci.joomla.org/joomla/joomla-cms/45273/1/6 .
Question: Have you tested if your code also works with PostgreSQL?