gabordemooij / redbean

ORM layer that creates models, config and database on the fly
https://www.redbeanphp.com
2.3k stars 280 forks source link

Why can't we use PascalCase column names? #930

Closed hamsbrar closed 1 year ago

hamsbrar commented 1 year ago

It looks like column names undergo a mandatory transformation into snake case.

I understand the rationale behind underscore(_) restrictions but can someone explain What's the issue with PascalCase?

gabordemooij commented 1 year ago

Because it is/was the most compatible way. Some OS/DB-versions are case insensitive.

hamsbrar commented 1 year ago

This explains why this the default behaviour but not why it's the only behaviour available.

This restriction, as it stands, disables all the valid use-cases of PascalCase. And if there are no reasons(apart from compatibility) then I think there should be an option to lift it. If I'm not mistaken, Redbean already provide options like exec, getRow for developers who are well aware of their DB/OS so it won't be first/or/the-only escape hatch.

Lynesth commented 1 year ago

Hi @hamsbrar

The reason it's now "the only behaviour available" was a choice by the creator of RedBean to keep things simple. But that doesn't mean a PR that adds the behaviour you wish for wouldn't be welcomed.

On a side note, you can still write your code using PascalCase to access beans properties (ie. $bean->MyProperty), as RedBean takes care of transforming that into snake_case before querying the database. But I assume it's the fact that the columns are not PascalCase in the database that bothers you?

hamsbrar commented 1 year ago

Hi!

was a choice by the creator of RedBean to keep things simple.

That is exactly why I like using it. I don't mind snake case everywhere but having no way to lift the restriction becomes an issue when dealing with an existing database that's using PascalCase everywhere.

But that doesn't mean a PR that adds the behaviour you wish for wouldn't be welcomed.

Good to know. I'll give it a try if @gabordemooij thinks the same.

$bean->MyProperty

This reminds me of an another thing. I tried supplying freeze=true in hope that it'll stop these transformations, which seem like a lot of unnecessary work, but it didn't.

Lynesth commented 1 year ago

You can use RedBeanPHP\Util\DispenseHelper::setEnforceNamingPolicy(false) to prevent it to change your tables names, but there isn't anything for columns at the moment.

Also, given that you're probably not using a database with case sensitive columns names anyway (and if you are, I'm curious as to what setup it is), and if you don't need to have RedBean modify the database (so if you can work in Frozen mode), then you can probably just write all your properties in lowercase.

R::setup( ... );
R::freeze(true);

$test = R::dispense('mytable');
$test->mycolumn = 'This works'; // column is actually 'MyColumn' in the db
R::store($test);

Probably not a real solution to your problem, but a solution nonetheless :)

hamsbrar commented 1 year ago

Take for example any database? the point is not that database treats columns names as case-insenstive. The point is that if you're using PascalCase on table names, the same casing has to be applied on column names. Letter casing is for mere readability and it's highly improbable that I'd would interpret "useremail" and "UserEmail" as distinct column references so I won't mind database making no distinction.

Interesting to see an example where case in-senstivity is helpful. I can change all properties to lowercase but like you said it's not a real solution. In fact it makes things worse because now I've to create accessors to all those properties – Again, for the sake of readability.

hamsbrar commented 1 year ago

RedBeanPHP\Util\DispenseHelper::setEnforceNamingPolicy(false)

This works for table names. Thanks.

Lynesth commented 1 year ago

If you're using FUSE Models, you can probably just get away changing their __get and __set by adding a little strtolower() in there.

If not, and if you're just working with a frozen database, modifying RedBean's code to add a

if ( ctype_upper( $property[0] ) ) return $property;

at the start of the OODBBean::beau() function should allow you to use PascalCase properties directly.

Note: None of this is tested, but it should work (again, just in Frozen mode, as Fluid mode includes schema checks which will most likely still not function). And this is just a fix so that you can get stuff working on your end without much hassle, it isn't a proper solution.

hamsbrar commented 1 year ago

I'll give it a try, this actually seems like an affordable option:)

Lynesth commented 1 year ago

Sure thing, lemme know if that worked out for you or not. :)

hamsbrar commented 1 year ago

At first, I thought beau might be a typo, and you actually meant bean. However, I found the beau and I did make the change to it as you suggested. But looks like id is hardcoded everywhere. I considered replacing every "id" with "Id", but then I noticed instances where it's single-quoted, like 'id' or '_id', '_id", $[arbitrary_identifier]->id, and so on. While I managed to make it work, I'm not entirely sure if those replace-all(s) had introduced any unintentional changes.

(Also, now I'm hesitant to create a PR; it's a extensive change.)

gabordemooij commented 1 year ago

Let's re-open this issue if it becomes relevant again.