FLOAT and the update_schema()

Discussion forum for Extension Writers regarding Extension Development.
User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

FLOAT and the update_schema()

Post by 3Di » Sat Dec 24, 2016 9:55 pm

Hi,
how you "transform" this total float(10,5) NOT NULL default '0',

into an acceptable format for db_tools?
May be 'total' => array('PDECIMAL' => 'decimal(10,5)', '0'),

I've read db/tools.php and lurked at Database_Type_Map already.
Just to confirm what I thought.

Thanks.
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

FLOAT and the update_schema() - creating a new datatypeype

Post by 3Di » Tue Jan 03, 2017 10:49 pm

Well, I am back on the bone,

tried everything available (I think) but no success, the best result (I expected this to be) was
total decimal(6,3) No 0.000
into the newly created table, that's the result of this
'total' => array('PDECIMAL', '0'),
wrote into the migration file that creates the schema, in fact.

I am thinking about to try and create a new DBAL datatype, is there any pointer to where to start from?
Say I would like the migration file to read and understand the new datatype, namely
'floating') --> decimal(10, 5)
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 3907
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: FLOAT and the update_schema()

Post by kasimi » Tue Jan 03, 2017 11:21 pm

You can use service replacement or service decoration with the dbal.tools service.

Then, define the new data types:

Code: Select all

$float_type = array(
	'mysql_41'		=> 'decimal(10, 5)',
	'mysql_40'		=> '...',
	'mssql'			=> '...',
	'mssqlnative'		=> '...',
	'oracle'		=> '...',
	'sqlite'		=> '...',
	'sqlite3'		=> '...',
	'postgres'		=> '...',
);
And finally add the new data types to the $dbms_type_map, preferably after the original constructor has been called:

Code: Select all

foreach ($float_type as $sql_layer => $type)
{
	$this->dbms_type_map[$sql_layer]['FLOAT'] = $type;
}

User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

Re: FLOAT and the update_schema()

Post by 3Di » Tue Jan 03, 2017 11:35 pm

You da man, way more elegant than the solution I found
(sort of making a private function that creates a switch on the sql_layer and - I can say - badly enough injects the new datatype within the migration)..

I was thinking about service decoration and you gave me the start. :)
Just one thing, I am porting a MOD to 3.1.x and service decoration is for 3.2, I will opt for service replacement. Any link to some extension that uses this, by any chance?

I will post back in case of problems or success. Thanks.
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 3907
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: FLOAT and the update_schema()

Post by kasimi » Tue Jan 03, 2017 11:59 pm

I haven't seen it used in the wild but here's a quick example.

Service definition:

Code: Select all

dbal.tools:
	class: 3di\ext\tools
	arguments:
		- '@dbal.conn'
And your tools class where you can add the code from my post above:

Code: Select all

namespace 3di\ext;

class tools extends \phpbb\db\tools
{
	public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false)
	{
		parent::__construct($db);
		// extend the $dbms_type_map here
	}
}

User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

Re: FLOAT and the update_schema()

Post by 3Di » Wed Jan 04, 2017 12:06 am

Me too I haven't found anything on the wild (github also deeply searched), I was just bound to read the core code, the constructor..

Code: Select all

	* Constructor. Set DB Object and set {@link $return_statements return_statements}.
	*
	* @param \phpbb\db\driver\driver_interface	$db					Database connection
	* @param bool		$return_statements	True if only statements should be returned and no SQL being executed
	*/
	public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false)
	{
		$this->db = $db;
		$this->return_statements = $return_statements;

		$this->dbms_type_map = self::get_dbms_type_map();
With your example I believe I am steps beyond in just a few minutes, I do appreciate. :)
Let me implement and test all of this and I will report here, for the posterity.
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
javiexin
Code Contributor
Posts: 1157
Joined: Wed Oct 12, 2011 11:46 pm
Location: Madrid, Spain
Name: Javier
Contact:

Re: FLOAT and the update_schema()

Post by javiexin » Wed Jan 04, 2017 12:28 am

I have a full working version of my Advanced Profile Fields extension that uses service replacement (in my case, of the Profile Fields manager). Not un GitHub as I was not planning to release it, in favor of another version that uses the ext class instead. Or maybe I will be lucky and my proposed changes will be merged into the core... Let me know if that would help.
-javiexin

User avatar
javiexin
Code Contributor
Posts: 1157
Joined: Wed Oct 12, 2011 11:46 pm
Location: Madrid, Spain
Name: Javier
Contact:

Re: FLOAT and the update_schema()

Post by javiexin » Wed Jan 04, 2017 12:48 pm

Ok, here it is what I did (the relevant parts, of course). Very similar to what kasimi suggested.
  1. Create a class that extends a base service class. In my case, I did use the apffwk/profilefields/manager.php file:

    Code: Select all

    namespace javiexin\apffwk\profilefields;
    
    class manager extends \phpbb\profilefields\manager
    {
    // class initialization and constructor, possibly calling parent::__construct, as kasimi indicated
    	public function disable_profilefields($profilefield_type_name)
    	{
    // my code goes here...
    	}
    	public function purge_profilefields($profilefield_type_name)
    	{
    // more code here
    	}
    	public function enable_profilefields($profilefield_type_name)
    	{
    // and yet more code
    	}
    }
    
  2. And, in apffwk/config/services.yml

    Code: Select all

    services:
        profilefields.manager:
            class: javiexin\apffwk\profilefields\manager
            arguments:
                - @auth
                - @dbal.conn
                - @dbal.tools
                - @dispatcher
                - @request
                - @template
                - @profilefields.type_collection
                - @user
                - @config_text
                - %tables.profile_fields%
                - %tables.profile_fields_language%
                - %tables.profile_fields_data%
    
Really, that is all it takes.

The problem for me was that these new service methods need to be called from the ext.php file of the extension, on enable/disable/purge of the extension. This is particular for MY case. And unfortunately, they are not YET available when this is executed (the ext enable method is called before the service class is instantiated), so you cannot use it from THE SAME extension, you must create two separate extensions, one providing the service, and another using it. AND the order of enablement is critical here... same as order of disablement. And given that the is no way to enforce these dependencies, it would create a somewhat complicated support issue.

Anyhow, I hope this helps...
-javiexin

User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

Re: FLOAT and the update_schema()

Post by 3Di » Wed Jan 04, 2017 5:50 pm

Thanks for the clarificatory example of what you was speaking about into your above posts, Javier.

For what I am seeing the service isn't available also during migrations, I get a
FLAG index unknown .. or the like..
while executing the migration schema update, using
'total' => array('FLOAT', '0'),
after having coded the services.yml file as

Code: Select all

services:
    dbal.tools:
        class: threedi\ext\tools
        arguments:
            - '@dbal.conn'
And created the tools.php class as

Code: Select all

namespace threedi\ext;

class tools extends \phpbb\db\tools
{
	public function __construct(\phpbb\db\driver\driver_interface $db, $return_statements = false)
	{
		parent::__construct($db);

		$float_type = array(
			'mysql_41'		=> 'decimal(10, 5)',
			'mysql_40'		=> 'decimal(10, 5)',
			'mssql'			=> '[float]',
			'mssqlnative'		=> '[float]',
			'oracle'		=> 'number(10, 5)',
			'sqlite'		=> 'decimal(10, 5)',
			'sqlite3'		=> 'decimal(10, 5)',
			'postgres'		=> 'decimal(10, 5)',
		);

		foreach ($float_type as $sql_layer => $type)
		{
			$this->dbms_type_map[$sql_layer]['FLOAT'] = $type;
		}
	}
}
If the service is called after ext.php and migrations (in sequence) then I have a couple of choice:
1 - create an helper extension for to make it available the service replacement to others
2 - using the approach I explained above in my firsts posts, not so elegant and a bit hackish though
3 - Just alter that column into the new table on user_setup (assuming the service replacement works after the extension is installed).

I have heard that making an helper extension that does nothing but just creates a "framewrok" for others will not pass the validation, there is a post in this forum.
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
javiexin
Code Contributor
Posts: 1157
Joined: Wed Oct 12, 2011 11:46 pm
Location: Madrid, Spain
Name: Javier
Contact:

Re: FLOAT and the update_schema()

Post by javiexin » Wed Jan 04, 2017 8:22 pm

3Di wrote: ↑
Wed Jan 04, 2017 5:50 pm
For what I am seeing the service isn't available also during migrations
During the migration of the extension itself? No, that is "before" enable of the extension.
For other extensions, it should work though.
3Di wrote: ↑
Wed Jan 04, 2017 5:50 pm
If the service is called after ext.php and migrations (in sequence) then I have a couple of choice:
1 - create an helper extension for to make it available the service replacement to others
A clear use case for my "Dependency Manager" :lol: . In fact, my need for that started with the above code...
3Di wrote: ↑
Wed Jan 04, 2017 5:50 pm
I have heard that making an helper extension that does nothing but just creates a "framewrok" for others will not pass the validation, there is a post in this forum.
I was not aware of this. In any case, that should not be a problem: your extension DOES provide a function, making new column types possible.

And an alternative would be to create a core patch, as an enhancement...
-javiexin

User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

Re: FLOAT and the update_schema()

Post by 3Di » Wed Jan 04, 2017 8:31 pm

javiexin wrote: ↑
Wed Jan 04, 2017 8:22 pm
I was not aware of this
Yes, it is one of those posts I was speaking and searching for a while, related to the other discussion we have had.. viewtopic.php?p=13867091#p13867091
javiexin wrote: ↑
Wed Jan 04, 2017 8:22 pm
During the migration of the extension itself? No, that is "before" enable of the extension.
For other extensions, it should work though.
I have do so some other tests before to decide what a do here, I would like to avoid the hackish method though.
javiexin wrote: ↑
Wed Jan 04, 2017 8:22 pm
A clear use case for my "Dependency Manager"
That will be tested, in the meantime I need to ship this one right or wrong, the going gets though..
time to get going has come. :)

Thanks.
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

Re: FLOAT and the update_schema()

Post by 3Di » Wed Jan 04, 2017 9:00 pm

javiexin wrote: ↑
Wed Jan 04, 2017 8:22 pm
And an alternative would be to create a core patch, as an enhancement...
I missed this point , yes.. I will nextly create a ticket for this. FWIW.
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 3907
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: FLOAT and the update_schema()

Post by kasimi » Wed Jan 04, 2017 9:05 pm

Sorry 3Di, sending you to a dead end was not my intention. :)

Here's the solution, and even though it might not be the most future-proof one it certainly is the easiest.

Make your migration extend phpbb\db\migration\container_aware_migration and do this in your update_schema() method:

Code: Select all

$float_type = array(
	...
);

$tools = $this->container->get('dbal.tools');
foreach ($float_type as $sql_layer => $type)
{
	$tools->dbms_type_map[$sql_layer]['FLOAT'] = $type;
}

return array(
	...
);
This works because the $dbms_type_map is declared as var which is equivalent to public.

User avatar
3Di
Former Team Member
Posts: 14229
Joined: Mon Apr 04, 2005 11:09 pm
Location: Milan (IT) Frankfurt (DE)
Name: Marco
Contact:

Re: FLOAT and the update_schema()

Post by 3Di » Wed Jan 04, 2017 9:15 pm

Don't worry kasimi, many thanks. :)
In my brain also this solution came in mind, but's not so easy to bring to life a workflow, despite is error-proof on the charts. I will try and report.

So, I have just to get rid of the service replacement and use the migration instead, am I correct?
Please PM me only to request paid works. Thx.
Want to compensate me for my interest? Donate
My development's activity ΒΊ PhpStorm's proud user
Extensions, Scripts, MOD porting, Update/Upgrades
πŸ‘¨β€πŸ« | Take a tour to | The Studio | πŸ‘¨β€πŸ«

User avatar
kasimi
Extension Customisations
Extension Customisations
Posts: 3907
Joined: Sat Sep 10, 2011 7:12 pm
Location: Germany
Contact:

Re: FLOAT and the update_schema()

Post by kasimi » Wed Jan 04, 2017 9:24 pm

Yes, it can be done entirely in the migration file, no service replacement.

Post Reply

Return to β€œExtension Writers Discussion”