Skip to content

Conversation

@1ma
Copy link
Contributor

@1ma 1ma commented Sep 13, 2018

Use case

I was trying to include a CREATE FUNCTION statement in a migration file, but I kept getting an unterminated dollar-quoted string at or near "$$ error. Upon inspection of the code I saw that the library explodes the whole content of the migration file at the semicolons, and the statement was being diced up in multiple parts.

Solution

As a workaround I made it explode at the ";\n" sequence, so you can select which semicolons you need to preserve with an innocuous comment.

Example

BEGIN; CREATE TABLE emp ( empname text, salary integer, last_date timestamp, last_user text ); CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$ BEGIN -- Check that empname and salary are given IF NEW.empname IS NULL THEN RAISE EXCEPTION 'empname cannot be null'; -- END IF; -- IF NEW.salary IS NULL THEN RAISE EXCEPTION '% cannot have null salary', NEW.empname; -- END IF; -- -- Who works for us when they must pay for it? IF NEW.salary < 0 THEN RAISE EXCEPTION '% cannot have a negative salary', NEW.empname; -- END IF; -- -- Remember who changed the payroll when NEW.last_date := current_timestamp; -- NEW.last_user := current_user; -- RETURN NEW; -- END; -- $emp_stamp$ LANGUAGE plpgsql; CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp FOR EACH ROW EXECUTE PROCEDURE emp_stamp(); COMMIT;

(Source: https://www.postgresql.org/docs/10/static/plpgsql-trigger.html)

PS It's ugly and hacky, but for now it works... Though it should be documented. If you accept this change I'd also like to contribute a small section on tips about writing plain SQL migrations. I've stumbled upon a few more gotchas.

@byjg
Copy link
Owner

byjg commented Sep 13, 2018

Thank you for your Pull Request. It is really well documented.

I believe your idea is good and totally makes sense for me. However there are 2 main issues about this:

  1. PHP_EOL is OS dependant. So Windows, Mac and Linux would produce different end of line
  2. The same is for the source of the SQL file. For example, if the SQL File was produce in Windows much probable to have \r\n instead only \n; the same for Mac that the EOL is \r.

So what do you think to change the explode for a preg_split?

<?php $sqlList = preg_split("/;(\r\n|\r|\n)/", "SELECT 1;\r\nSELECT 2;\nSELECT 3;\rSELECT 4;"); print_r($sqlList);

Please do this change and I'll approve it.

@1ma
Copy link
Contributor Author

1ma commented Sep 14, 2018

Yes, I settled on PHP_EOL because I thought that people developing on Windows would also run their migrations on Windows (same for Linux and Mac), but this is probably a bit of a stretch. OTOH your solution should work on any scenario and never "surprise" anyone, so I'm gonna change it right away.

@1ma
Copy link
Contributor Author

1ma commented Sep 14, 2018

PS You've got your .idea folder in the source tree, mind if I delete it? I see that it is already ignored in the .gitignore file.

@byjg
Copy link
Owner

byjg commented Sep 14, 2018

Thank you!

About the .idea folder, there is no necessary to remove. I only shared the folder .idea/runConfigurations. I just share some run configurations.

@1ma
Copy link
Contributor Author

1ma commented Sep 14, 2018

Aite then, your rules :) It's done.

@byjg byjg changed the base branch from master to 2.1.0 September 14, 2018 01:08
@byjg byjg merged commit 2895f87 into byjg:2.1.0 Sep 14, 2018
@byjg
Copy link
Owner

byjg commented Sep 14, 2018

Hi merge into the branch 2.1.0. Until next week will merge into the master. For while, you can use the version: 2.1.0.x-dev in your composer file.

@1ma 1ma deleted the feature-migrate-functions branch September 14, 2018 01:18
@1ma 1ma mentioned this pull request Sep 14, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants