如何将排序描述符和谓词与核心数据可转换字段一起使用?
我有一个我编写的应用程序,它曾经工作得很好。现在有一个新的要求,即所有数据都需要加密,因此我通过使所有核心数据字段类型可转换并为每种数据类型编写自定义转换器来实现加密,该转换器在从数据写入/读取时加密/解密每个数据元素。核心数据存储。
加密工作正常,我可以看到所有数据。问题在于排序似乎被破坏了,就像任何稍微复杂的谓词(包括子查询的谓词)一样。
我猜测在通过转换器发送值之前会对这些值进行排序(即对加密值进行排序)。有什么办法可以解决这个问题吗?我想我可以尝试使用排序描述符并指定我自己的选择器来进行比较并首先显式解密值。如果有效的话我会在这里发帖。
不过,谓词情况是一个更大的问题。奇怪的是,它似乎大部分工作正常,但当我执行子查询时(就像关系中两个对象的联接),它会失败。使用可转换值和谓词时是否存在已知问题,或者我的变压器中可能存在错误?
下面是一个不再起作用的谓词示例:
[NSPredicate predicateWithFormat:@"isdeleted == NO AND (SUBQUERY(appuserMessages, $am, $am.recAppUserID == %@ AND $am.isTrash == NO).@count > 0)", appuserid];
该谓词在与 AppuserMessages 具有一对多关系的 Messages 对象上执行。该谓词应该返回所有未被 isdeleted 且至少有一条 appuserMessage 的消息,其中 recAppUserID 为 appuserid 并且 isTrash 为 false。它曾经有效,但现在没有任何返回。
I have an application which I wrote which used to work perfectly fine. There is new requirement that all data needs to be encrypted now, so I implemented encryption by making all my core data fields type transformable and writing custom transformers for each data type which encrypts/decrypts each element of data as it is written/read from the core data store.
The encryption works fine and I can see all the data. The problem is that sorting appears to be broken as does any even slightly complicated predicate (the ones that include subqueries).
I'm guessing that the sorting is being done on the values before they are sent through the transformer (namely, sorting is being done on the encrypted values). Is there a way I can get around this? I suppose I can try using a sort descriptor and specify my own selector to do the comparison and explicitly decrypt the values first. I'll post here if that works.
The predicate situation is a bigger problem though. It's strange that it seems to mostly work but then fails when I do subqueries (which are like joins across two objects in a relationship). Is there a known problem when using transformable values and predicates or maybe I have a bug in my transformers?
Here is an example of a predicate that no longer works:
[NSPredicate predicateWithFormat:@"isdeleted == NO AND (SUBQUERY(appuserMessages, $am, $am.recAppUserID == %@ AND $am.isTrash == NO).@count > 0)", appuserid];
The predicate is performed on the Messages object which has a one-to-many relationship with AppuserMessages. This predicate is supposed to return all messages that are not isdeleted and have at least one appuserMessage where the recAppUserID is appuserid and isTrash is false. It used to work, but now returns nothing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
从更多的实验来看,当您具有可转换的数据类型时,子查询似乎根本不起作用。
排序描述符也不起作用,这是可以理解的原因。排序委托给数据库引擎来完成,因此排序是在转换前的行上完成的。就我而言,这意味着它们是根据(随机)加密值而不是解密值进行排序的。
唯一的解决方案似乎是将行提取到可变数组中,然后对数组执行排序(使用 sortWithDescriptors)。
至于子查询,我假设它有类似的问题。可能子查询是由数据库引擎预转换完成的,因此总是失败。同样,解决方案是在获取中执行尽可能复杂的查询,然后使用结果的可变数组上的过滤器执行查询的其余部分(子查询部分)。
From more experimentation it seems that subquerys simply won't work when you have transformable data types.
Sort descriptors won't work either and it is understandable why. The sorting is left delegated to the database engine to do, so the sorting is done on the rows pre-transformation. In my case, that means they are sorted based on their (random) encrypted values instead of the decrypted ones.
The only solution seems to be to fetch the rows into an mutable array and then perform the sort on the array (using sortWithDescriptors).
As for the subqueries, I'm assuming its a similar problem. Probably the subquery is done by the database engine pre-transformation and therefore always fails. Again, the solution is to do as complicated as a query as you can in the fetch and then the rest of the query (the subquery part) with a filter on a mutable array of the results.