? Pending

User tests: Successful: Unsuccessful:

avatar korenevskiy
korenevskiy
21 Jun 2021

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.

avatar korenevskiy korenevskiy - open - 21 Jun 2021
avatar korenevskiy korenevskiy - change - 21 Jun 2021
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 21 Jun 2021
Category Libraries
avatar richard67
richard67 - comment - 21 Jun 2021

@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?

avatar korenevskiy korenevskiy - change - 21 Jun 2021
Labels Added: ?
avatar brianteeman
brianteeman - comment - 21 Jun 2021

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.

avatar HLeithner
HLeithner - comment - 21 Jun 2021

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.

avatar korenevskiy
korenevskiy - comment - 21 Jun 2021

@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

avatar richard67
richard67 - comment - 21 Jun 2021

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.

avatar korenevskiy
korenevskiy - comment - 21 Jun 2021

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.

avatar korenevskiy
korenevskiy - comment - 21 Jun 2021

@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?

avatar korenevskiy
korenevskiy - comment - 21 Jun 2021

@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.

avatar korenevskiy
korenevskiy - comment - 21 Jun 2021

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?

avatar korenevskiy
korenevskiy - comment - 21 Jun 2021

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.

avatar korenevskiy
korenevskiy - comment - 21 Jun 2021

@brianteeman
The code contains methods
ReflectionProperty::getType();

This method appeared in PHP 7.4.

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.

Maybe you need to move typing support to Joomla 4.1.

But then you need to raise support for Joomla 4.1 to PHP 7.4 (8.0)

avatar brianteeman
brianteeman - comment - 21 Jun 2021

@HLeithner answered my question so time must be spent concentrating on releasing 4.0 and anything else can wait

avatar korenevskiy
korenevskiy - comment - 22 Jun 2021

@brianteeman

@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?

avatar HLeithner
HLeithner - comment - 22 Jun 2021

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.

avatar korenevskiy
korenevskiy - comment - 22 Jun 2021

@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.

avatar korenevskiy
korenevskiy - comment - 22 Jun 2021

I now still ruled the table. I deleted the code I wrote in several places, and optimized some things.

avatar korenevskiy
korenevskiy - comment - 27 Jun 2021

@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.

avatar richard67
richard67 - comment - 27 Jun 2021

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.

avatar korenevskiy korenevskiy - change - 20 Aug 2021
Labels Added: ?
Removed: ?
avatar korenevskiy
korenevskiy - comment - 20 Aug 2021

I have recreated the PR in the next version of Joomla 4.1

avatar korenevskiy
korenevskiy - comment - 20 Aug 2021

I have recreated the PR in the next version of Joomla 4.1
#35247

avatar korenevskiy korenevskiy - change - 20 Aug 2021
Status Pending Closed
Closed_Date 0000-00-00 00:00:00 2021-08-20 07:45:00
Closed_By korenevskiy
Labels Added: ?
Removed: ?
avatar korenevskiy korenevskiy - close - 20 Aug 2021
avatar richard67
richard67 - comment - 20 Aug 2021

@korenevskiy Does it replace this PR? If so, please close.

avatar korenevskiy
korenevskiy - comment - 20 Aug 2021

@korenevskiy Does it replace this PR? If so, please close.

OK, I've already closed it.

Add a Comment

Login with GitHub to post a comment