Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Sam Bosley
@sbosley
@jdkoren I wonder if we should make a first-class plugin to make it easier to define custom superclasses? or even just bake that functionality into the existing annotations? like in @TableModelSpec we could have Class<? extends TableModel> superclass() default TableModel.class. this would require some dependency wrangling but might be useful...
I also see the appeal of defining some interfaces for our model objects but that's a big refactor to a lot of stuff, so I'm not sure if/when I could get to that
Sam Bosley
@sbosley
TableModel on its own is a pretty small interface, but the interface we'd actually need to pull out would be that of AbstractModel, which is huge, so we'd have to apply any such interface refactor to all things that touch AbstractModel, TableModel, or ViewModel. it would be a lot easier if we could use default methods on the interfaces, but it looks like Android currently only supports that on API 24+
anyways @MFlisar, thanks for the suggestion! I do like the idea of pulling out some of these interfaces and your use case makes sense, so I'll put it down as something to consider for our 4.0 version. in the meantime I definitely recommend using the intersection type approach (this is what I've always done for similar problems, although it's only come up once or twice which is part of why we've never done it any other way) or try the superclass approach
Aranda Morrison
@Aranda
Hi all! I'm investigating using JSONColumnin a cross platform project. Are there examples of a JSONObjectMapper for iOS?
Sam Bosley
@sbosley
@Aranda I hacked one together using the org.json classes once. you can see a partial example in the unit test suite here, but this is a partial example using only a few select classes, so it's not very general. I implemented a more general one for another project at once using code generation to generate the boilerplate of constructing real objects from org.json, but I'm afraid that implementation isn't open sourced.
all that being said though, I'm told that GSON is compatible with j2objc (which makes total sense as they're both made by Google), although I have not tried integrating it into a project myself. if you can get it working though, it should be a great implementation of JSONMapper on both platforms. you can see an example of how I set it up for the android unit tests here
Aranda Morrison
@Aranda
Thanks... interesting, I had thought GSON was out of the picture for iOS. If not, then great!
Sam Bosley
@sbosley
MFlisar
@MFlisar
Is it possbible to tell squidb to generate setters with void as return value? Maybe useful for some interface, otherwise I have to use field names that are different and write model methods (which is possible, but may be a lot of unnecessary work in some cases)
MFlisar
@MFlisar

Another question: can I make a model implement an interface with multiple paramters?
Following

    @TableModelSpec(className = "DesktopItem", tableName = "desktopItem")
    @Implements(interfaceDefinitions = {@Implements.InterfaceSpec(interfaceClass=Item.class, interfaceTypeArgs={DesktopItem.class, Long.class})})
    public class DesktopItemEntrySpec

Generates this:

    public class DesktopItem extends AndroidTableModel implements Item<Long>

So the generated class is missing the DesktopItem paramaeter in the interface...

MFlisar
@MFlisar
EDIT: changing the implements line to @Implements(interfaceDefinitions = {@Implements.InterfaceSpec(interfaceClass=Item.class, interfaceTypeArgNames={"com.my.package.DesktopItem", "java.lang.Long"})}) works, but using classes instead of strings would be more beautiful...
Sam Bosley
@sbosley
@MFlisar for the return values of setters, there are a couple ways to do it using code generation plugins. the easiest way is probably to disable the default getters and setters using the disableGettersAndSetters flag (documented here), and defining a new code generation plugin that scans the list of each model's properties and generates getters and setters using the interface that you would prefer. you can look at the BasicPropertyGeneratorclass to see how that class creates getter/setter definitions, and take inspiration from that.
as for using a class in the @Implements.InterfaceSpec type args, the reason it's not working is because you can't refer to a class object of a generated class while you're generating that class -- it doesn't exist at compile time, so the annotation processing APIs can't pick up the package name. using the fully qualified class name is the correct solution, and that's why that option exists
MFlisar
@MFlisar
@sbosley ok thanks, that makes sense and helps me
MFlisar
@MFlisar

Is it possible to overwrite a generated model method? Like following:

@ColumnSpec(name = "name", defaultValue = "")
String name;

@ModelMethod
public static String getName(CustomItem item) {
    // custom code...
    return ...;
}

The ModelMethod will throw an exception because the generated model has this function already...

I know I can solve it by renaming the field name and then I can define my custom getName function, I'm just interested if there is a way to overwrite the generated method instead

Sam Bosley
@sbosley
@MFlisar yep, the @ModelMethod annotation has an optional name parameter. so it'd just look like:
@ModelMethod(name = "customMethodName")
public static String getName(CustomItem item) {
    // custom code...
    return ...;
}
MFlisar
@MFlisar
@sbosley I try this, but I think that's something else than what I want... Will this REPLACE the automatically generated getName method? Because this is what I want...
Sam Bosley
@sbosley
@MFlisar ah I see, I thought you were referring to the generated model method, not the generated getter. in that case your only option is a code generation plugin. if I understand what you're trying to do correctly, you'd probably want a custom subclass of TableModelSpecFieldPlugin as well as custom subclasses of the BasicPropertyGenerator classes for different field types, i.e. BasicStringPropertyGenerator, BasicLongPropertyGenerator, etc. your custom property generator subclasses could look for specific annotations on their fields and override methods such as getterMethodName or writeGetterBody in order to customize the implementation details of your accessors. (at this time you can't skip generating getters/setters entirely, but you could you just design your annotations such that they caused the getter to delegate to a private model method, or you could make the getter name different and the method private). you'd need to register your custom property generator classes with your subclass of TableModelSpecFieldPlugin by overriding the methods such as getStringPropertyGenerator and getLongPropertyGenerator. hope that makes sense!
MFlisar
@MFlisar
@sbosley Ok, thanks. Then I stay with what I have and use a ModelMethod and use this one. And my model uses a field like internalName instead of name so I can use the getName which is an interface method I use in a lot of other models as well... That's the more simple solution.
Elliot Bulmer
@egbulmer
Hi Everyone! I'm working on integrating Kotlin into an existing Android application that uses SquiDB. All of our spec classes (e.g. @TableModelSpec) are currently written in Java. When I try to use one of these classes from Kotlin I get a symbol not found error from the compiler. Issues #278 and #166 seem related. What I'm wondering is if this is a supported use-case in SquiDB? Or would we need to do something like port our existing spec classes to Kotlin and use kapt?
Sam Bosley
@sbosley
hi @sonelliot! I believe that you can keep your models in Java and just use kapt -- while I haven't done much with kotlin myself, my understanding is that you just need to use that to configure both java and kotlin annotation processing when using the kotlin plugin. I think this is the same issue as #278 -- I just realized that a user submitted a pull request to clarify the readme for this issue that I missed, I should get that in :) hope that helps! definitely post back here if things still seem amiss
Elliot Bulmer
@egbulmer
Thanks @sbosley! That's probably what the problem is. Cheers. :D
Amine Laadhari
@aminelaadhari
Hi Guys, is suqidb working with xcode 9? We tried and we found an issue when we use the in Criterion. It looks like it looses the collection of values. I double checked the list multiple times and it has values.
[ERROR] : Task - unobservedException Optional("Index: 0, Size: 0")
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at 0x0000000102b20cc2 java.util.ArrayList.get() + 110
at 0x000000010328b9a2 com.yahoo.squidb.sql.CompiledArgumentResolver.resolveSqlString() + 610
at 0x000000010328b1b2 com.yahoo.squidb.sql.CompiledArgumentResolver.resolveToCompiledStatement() + 114
at 0x0000000103015ba5 com.yahoo.squidb.sql.TableStatement.compile() + 213
at 0x0000000103015c41 com.yahoo.squidb.sql.TableStatement.compile() + 33
at 0x000000010314d387 com.yahoo.squidb.data.SquidDatabase.query() + 119
at 0x00000001032d3ed5 co.thefabulous.shared.data.source.HabitRepository.getById() + 405
Sam Bosley
@sbosley
hey @aminelaadhari, haven't used it with xcode 9 yet myself. what version of j2objc are you using? can you create a unit test that fails when compiled with j2objc directly?
Sam Bosley
@sbosley
also which version of squidb?
Sam Bosley
@sbosley
based on the exception, I'd guess that when the arguments to the statement are resolved, the argument in the in Criterion does not return true for instanceof java.util.Collection<?>. can you provide a brief code sample for how you're constructing the in Criterion? might help us to track down if there's some kind of bug with how j2objc translates things (I'm assuming this issue doesn't happen in java)
Amine Laadhari
@aminelaadhari
Hey @sbosley we use j2obj 2.0.5 (the last version) and suqibdb 3.2.3. I will try to create the juint test!
We had to change the ios native files to make it work
(some missing @property(copy))
Sam Bosley
@sbosley
ok, thanks! I've made some changes for j2objc 2.x on our dev_4.0 branch but have not tested with any versions of j2objc after 1.3.1. unfortunately I don't have access to a dev environment right now (moving this weekend and all my real computers are packed up) but I can take a closer look on monday
what were the @property changes you needed to make? I don't think I encountered those when I was experimenting with j2objc 2
Amine Laadhari
@aminelaadhari
2 files: CursorWindowNative.h line 108: @property(copy) NSString mName;
SQLiteConnectionNative.h line 30 and 31: @property(copy) NSString
path;
@property(copy) NSString *label;
We create the Criterion in a very simple manner:
public List<Habit> getById(List<String> ids) {
        SquidCursor<Habit> cur = db.query(Habit.class, Query.select(Habit.PROPERTIES).where(Habit.UID.in(ids)));

        return habitCursorToList(cur);
    }
Sam Bosley
@sbosley
yep that should be fine on the java side. my guess (with no hard evidence at all so I could be totally wrong) is that something in the translation is causing the list to not be an instance of java.util.Collection when compiled for iOS
thanks for the heads up about the @property stuff. I'm not well versed in obj-c at all, what does that change do?
I'm assuming that it copies the values when assigning them but that seems like an odd necessity for strings, since strings should be immutable
Amine Laadhari
@aminelaadhari
Me neither but the compiler was raising an error. For string properties we have to explicitly choose the type of assingement (assign, copy or retain) I think
I used copy just to make it work, not sure about it though
Sam Bosley
@sbosley
huh! didn't know. thanks for the heads up. copy should be fine, and actually it's probably a good idea in case the caller passes in an NSMutableString on the iOS side
I wonder if that's a new thing in Xcode 9 that they introduced to guard against exactly that kind of bug. I'll definitely get those changes into our 4.0 branch
Amine Laadhari
@aminelaadhari
Concerning not an instance of Collection: I tried using a forced ArrayList. I had the issue. What's is strange is we have the issue only with xcode 9 and not 8
Sam Bosley
@sbosley
yeah that's definitely weird. I'll be curious to see if we can reproduce the issue when compiling with j2objc from the command line outside of xcode
all Lists should also be Collections though, since List extends Collection. I'll probably need to examine the translated code and do some debug stepping to track down the problem
if you would like to debug on your own before I can look at it on monday, you could add some logging to InCollectionCriterion to make sure it's adding your argument as a collection, and also add some logging to the private findCollectionArgs method in CompiledArgumentResolver to see if that is in turn finding your collection args.
Amine Laadhari
@aminelaadhari
sure I will do that
thanks!
Sam Bosley
@sbosley
if the logging doesn't reveal anything interesting about whether or not things are collections, I could be way off in my guess :) but based on the exception that's what it seems like. findCollectionArgs looks through the argument list for anything that's a collection, and adds it to the collectionArgs field in CompiledArgumentResolver. line 94 in that class extracts them: Collection<?> values = collectionArgs.get(index);, but the exception indicates the list is empty. it'll be illuminating to understand why it's empty
I'm sure your list has arguments, but it seems like the list of lists that we keep internally isn't being populated, and that's what's throwing the exception
@aminelaadhari I just came across this: https://groups.google.com/forum/#!topic/j2objc-discuss/avy79pz1XxU/discussion. not sure if its the same issue, but it sounds similar to what you're experiencing