Git Product home page Git Product logo

atlas.mapper's People

Contributors

conlanpatrek avatar elgigi avatar far-blue avatar jakejohns avatar pmjones avatar sunkan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

atlas.mapper's Issues

fixForeignRecord crash on deleted Records

This code will crash with TokenRow::$account_id is immutable after Row is deleted

$account = $mapper->fetchRecord(1, ['tokens']);

$token = $account->tokens->getOneBy(['type' => 'test']);

if (isValid($token)) {
    $atlas->delete($token);
}

$account->modified = date('c');
$atlas->update($account);

Is this the intended behavior?

Ps.
I found out will writing this issue that I can use detachOneBy instead of getOneBy but that's not always what you want.

Ps 2.
Also found the detachDeleted method.

We should probably update the documentation with a not about this behavior

public access to the foreign mapper class or classname in MapperRelationship

Hello,

I'm trying to remove some repetitive, boilerplate code in our app models and one of the areas we see a lot of repeated code is in handling the creation of new records with related fields. When you create a new record none of the related fields will be setup - they are all null - so when we come to set values on them we first need to create the appropriate Record or RecordSet class. While I don't intend to blanket-create these empty classes on record creation I would like to create a simple function that will handle it.

At the moment there is no way to retrieve the foreign mapper class name so any util code would still need to accept the class of the foreign mapper as a parameter. If either the MapperRelationships::getForeignMapper() function was public or there was a public MapperRelationships::getForeignMapperClass() method similar to the Record::getMapperClass() method then I could remove a lot of hard-coded class names and simplify our code by being able to look up the mapper class based on the related field name.

The only way to achieve something similar at the moment is via the stitchIntoRecords() method but this makes unneeded db calls.

Would anyone object to such as change?

Significant inefficiencies in stitchIntoRecord

Hi all,

I'm testing pushing real-world levels of data through a microservice I've written using Atlas and I've noticed some significant inefficiencies in the various stitchIntoRecord methods.

For instance, the OneToOne class method in combination with RegularRelationship's stitchIntoMethods() method basically loops through every nativeRecord in turn and then loops through every foreignRecord to match them up. However, it neither exits early when a match is found nor removed matched foreignRecords. So with 1000 nativeRecords and their associated 1000 foreignRecords you end up with 1,000,000 calls to recordsMatch().

I'd like to suggest that:

  • The stitchIntoRecord abstract be adjusted to accept the foreignRecords array by reference
  • The OneToOne method both removes a matched foreignRecord and also breaks the loop early
  • The ManyToOne method breaks early but doesn't remove the foreignRecord from the array
  • The OneToMany method removes the matched foreignRecord from the array but doesn't break the loop early.

I don't think there are further optimisations available for the other relationship types.

In the case of OneToOne the result is a change from O(n^2) to O(2n). In testing with 3000 records in my app this changed execution time from over 2 mins to 5 seconds.

Do these changes sound correct and reasonable or have I missed something? If there's no reason against the changes I'm happy to put together a PR.

One point with these changes will be that in the case of duplicate records the behaviour will change. If there are duplicates foreignRecord entries, where currently the last record that matches in the foreignRecords array will always be assigned with my changes the first will be assigned instead for OneToOne and ManyToOne. If there are duplicate nativeRecord entries, where currently all duplicates will receive the same foreignRecord they will now receive different ones and possibly no match will be found for duplicates in the case of OneToOne and OneToMany as the foreignRecord entries are removed as they are consumed.

Thoughts from anyone?

Option to always include the related table in a 'with' for a oneToOne relationship

Hello :)

I have a few oneToOne table relationships where I always want the related data. Rather than having to remember to 'with' the related table each time, it would be nice to be able to specify when defining the relationship that the related table data is always fetched.

Alternatively, is there a recommended way to catch and modify the underlying calls to inject an additional 'with' in a custom subclass somewhere?

I'm not sure if here or the Orm repo is the best place for this issue / question / feature request but I figured I'd try here first :)

Thanks!

Performance issues with many-to-many relationships

Hi all,

There's a performance issue with large many-to-many relationships due to very large numbers of calls to recordsMatch. I've submitted PR #17 with a suggested approach to optimising the code that in my testing significantly reduced execution time. Comments and thoughts welcome :D

Need to refresh record stored in Mapper::identityMap

I am using the new Symfony Flex bundle. I have a long running process. I am creating a new row in a table, then waiting for a semaphore, and reading the row again as it has changed in the meantime.

Similarly, I want to be able to create a new row and then re-read it as MySQL executes a trigger that amends values. I am not able to retrieve the updated row values.

It seems the row is stored in Mapper::identityMap so I am getting back the original array passed through; not the updated row from the database.

I cannot see a way to force a refresh so the row is actually read from the database.

Thoughts?

[QUESTION] Order of relationship

Hi,

How we can order the relationship ?

Example, if a have a "project" and associates "tasks", and each "task" has priority value.
I give tasks to project with 'with()' method, but I am unable to order the tasks by a column name.In Realtionship objects, i am able to filter with where with method '\Atlas\Mapper\Relationship\Relationship::where' but not ordering.

Thanks.

[QUESTION] Create mapper-subselect

How can I create, from a MapperSelect, another MapperSelect to use in a join on the main query?

Right now I'm creating the 2 MapperSelects separated, then turning the second into a string and passing the bindvalues by hand.

The problem is that the bindings values colide, from the use of bindinline on both.

Something like:

/* @var $atlas \Atlas\Orm\Atlas */
$select = $atlas->select('table1')->(...);
$select2 = $atlas->select('table2')->(...);

$select2String = $select2->getStatement();
$select->join('INNER' , '('.$select2String.') as t2', 'table2.id = table.table2_id');
$bindValues = [];
foreach ($select2->getBindValues() as $bindKey => $bindValue) {
   $bindValues[$bindKey] = $bindValue[0];
}
$select->bindValues($bindValues);

Results in:

select
	*
from
	table1
inner join (
		select *
	from table2
	where
		table2.id = :__1__
		) t2 on t2.id = table1.table2_id
where
	table1.id = :__1__

Table1 has a relationship to table2, but instead of using a simple join, I want to use a subselect to keep separated scopes. This is useful especially because I'm reusing the 2nd select.

Thank you for the help.

Error thrown when fetching record set when all records are in the identity map

This may not be the repo to fix this in (it may be an issue building the query, not sure), so if I need to repost this issue somewhere else I'll be happy to do so. Just let me know.

Noted that when calling Mapper->fetchRecords(), that if all of the records are in the identity map, then a malformed sql string is built and an error is thrown.

Here's a minimal recreation:

$primaryKey = 'A_LEGIT_PRIMARY_KEY';
$mapper->fetchRecord($primaryKey); // primes the identity cache for illustration purposes.
$mapper->fetchRecords([$primaryKey]); // throws

The issue is that in Mapper.php:104 we're querying for all of the non-identity-map cached rows in the set ($this->table->selectRows($this->select(), $missing)).$missing is an empty array if we've already cached all of the records belonging to the primary keys we're interested in. The resulting sequel ends in a clause that looks like this: WHERE id IN (), which isn't supported, at least in MySQL 8 or 5.7.

My gut says that the preferable way to solve this is to allow for querying an empty set like this. I've seen suggested elsewhere that you drop-in replace WHERE {col} IN () with any clause that evaluates to false... so WHERE NULL IS NOT NULL or something. You can do the inverse for NOT IN empty sets (WHERE NULL IS NULL). I don't know where this code lives, though.

The other thought I had is to just hold back on the selectRows call when $missing is empty. It's less preferable in my mind, but I think this largely depends on how uncomfortable you are with making the query builder smarter.

Let me know your thoughts.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.