Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
Amine Laadhari
@aminelaadhari
The workaround fixes the issue :)
WizzCad
@WizzCad
Hi everyone ! I'm interested by SquiDB for a cross platform dev and would like to know if a ModelSpec class can extends another class that contains common fields used by many tables like ids, creation and update dates and creation and update authors. I need these fields in almost all my tables (around 30 in total) and would like to avoid the copy paste :) I have tried to extend class but generator don't take it in count and didn't find anything in code about that point... Thanks !
Sam Bosley
@sbosley
hey @WizzCad, great question. unfortunately we don't have first class support for that at the moment -- it's been on my radar to add to 4.0 for a long time, but I've sadly had very little time for active development lately. I would suggest the following as a workaround -- if it's always the same collection of columns that you're wanting to use in all your models, you could create a code generation plugin for those columns at compile time and add them into the code generator's internal representation of the model spec so they all get picked up and generated. you might even be able to make a code generation plugin to scan a superclass of a model spec (which is what we'd eventually do when adding first-class support for this), although it would be a bit more complicated and require slightly deeper knowledge of the java annotation processing APIs. there is some documentation you can find on writing code generation plugins here: https://github.com/yahoo/squidb/wiki/Taking-control-of-code-generation. I also rewrote the entire code generator on our dev_4.0 branch some time ago with a much improved plugin API based on square's javapoet, so if you'd like to use the cutting edge you might have an easier time with creating your own codegen hooks, although it's not as well documented as the 3.0 version. either way, happy to offer more detailed assistance if that sounds like an approach you're open to!
MFlisar
@MFlisar
Is there some way to safely deprecate database fields that are not used anymore? E.g. I have a field that's called "name" and then I upgrade my table to have a field called "firstname" and "secondname" and I deprecate the "name" field. I don't remove it from the table as there is no way to delete a column from sql without creating a new table and copying everything over, deleting the original table and renaming the copy. I want to keep the field in my specs file and want that the compiler throws a build exception if I ever again declare a field with the database name "name". Is something like this supported? Any security mechanism I can use to avoid creating new fields that may exist in some version of my app to avoid conflicts because of this?
Sam Bosley
@sbosley

@MFlisar you can mark fields in your model spec with @Deprecated. this will have the following effects:
1) the column will no longer be included in any newly created tables (but as you say will still exist in existing ones)
2) no getter or setter will be generated in the model for the column
3) a corresponding @Deprecated property for the column will still be generated in the model spec, to assist in writing database migrations using that column

validation to protect you from reintroducing the column name later isn't part of this -- I can definitely imagine a scenario where users might want to repurpose or undeprecate a column using e.g. a different type, so I would be hesitant to have forbidding that be the default. but you could easily implement such validation yourself using a code generation plugin that scans your list of regular and deprecated properties to look for any name duplications

MFlisar
@MFlisar

Of course it would be nice to only optionally makr a field name as unusable like @Deprecated(reuseageAllow = false) or similar. Actually, because of different column type this would be nice. Consider having a column used with an int value, then you deprecate it and half a year later you introduce a new column with the same name but a string value. Tests won't show you any errors, you make a new release and get crashes because of missmatching column types.

In this case it would be nice to get an information that the column name may already exist on some users device so that I can change @Deprecated(reuseageAllow = false) to @Deprecatedand make sure that I write the correct migration code - in this case I would have to delete the old column via a temp intermediate table.

Currently I prefer using following alternative solution that solves this problem over using @Deprecated:

// renaming the field and use the old olumn name
// to make sure to get duplication errors in generated code if the name is reused
@ColumnSpec(name = "name")
String _deprecated1;

Just because this way I get an exception in database creation because of duplicate field names. So testing my app in the emulator will immediately show me that I have a problem...

Still I would prefer an annotation processor exception instead, it should check if a field name and a deprecated field name with reuseageAllow = false exists and throw a generation error... Imho, this would be very nice and would help improving safety...

WizzCad
@WizzCad
@sbosley Thanks for quick your answer ! I'll check that :)
Sam Bosley
@sbosley
@MFlisar good points. of course, @Deprecated(reusageAllow = false) would require a custom @Deprecated annotation that would shadow the default Java one which might not be great, but we could name it something else. although, you might have convinced me -- disallowing reusing a name as the default might not be so bad, because you could always get around it by simply removing the deprecated column altogether and fully replacing it with your new one. you'd have to be careful with your migrations in such a case, but you could do it. as I mentioned I haven't had time for much active development lately, but we've been introducing a lot more compile time code validation in the 4.0 dev branch so I could look into adding it there, and as I mentioned a simple code generation plugin would also definitely work
MFlisar
@MFlisar
The name was just a quick idea, it's not good I know. I personally don't mind what the default behaviour is (although my personal opinion is safety first, so the build should fail by default if you ask me) as long as I get the possibility to do what I want. Thanks for considering this feature.
ujagarsingh
@ujagarsingh
Hi, @MFlisar thanks for reply. i am using squidb and now i want use procedure in squidb. so how can i do
Sam Bosley
@sbosley
@ujagarsingh what exactly do you mean by "use a procedure"? do you mean a SQL query?
ujagarsingh
@ujagarsingh
i mean stored procedure. just like mysql
exapmle-> CREATE PROCEDURE new_procedure ()
BEGIN
select * from user
END
Sam Bosley
@sbosley
I'm actually not familiar with MySQL stored procedures. squidb is a SQLite library and as such only supports SQLite features; I don't believe that SQLite has such a concept
however, you can define methods in java to do whatever read/write operations you want
ujagarsingh
@ujagarsingh
Thank You so much for Information .
Sam Bosley
@sbosley
so by way of your example, you'd define:
public SquidCursor<User> getUsers() {
    return mySquidDatabase.query(User.class, Query.select()); // Equivalent to select * from users
}
or, to parameterize things:
public SquidCursor<User> getUsers(int minimumAge) {
    // Equivalent to select * from users where users.age >= minimumAge
    return mySquidDatabase.query(User.class, Query.select().where(User.AGE.gte(minimumAge)));
}
pretty much you just define java methods with whatever parameters you need, and convert that into queries or transactions that you can execute on an instance of SquidDatabase
ujagarsingh
@ujagarsingh
can i pass this function in query. when i want to run my query. just like 'call getusers()'.
Sam Bosley
@sbosley
not in the way you're thinking of. SQLite just has no concept of stored procedures in the way you're describing (I'm trying to read about them in parallel right now)
you can use subqueries or views to refer to other queries at the SQL level
or you can define java methods for common tasks at the application level
maybe if you give me a more concrete example of the task you're trying to accomplish I can help with other suggestions
ujagarsingh
@ujagarsingh
thank you so much @sbosley for helped us. i give you task detail if i have some problem and not resolved as your suggestion.
Sam Bosley
@sbosley
:+1: sounds good!
John L. Jegutanis
@erasmospunk
Hello. I am using a shared "core" library that is shared between android and ios.
I wanted to include the squidb + annotations without the squidb-android in the core library and include it in the android project.
Unfortunately I get errors that go away if I add all the related squidb dependencies to the android project and remove everything from the core library.
Is there a way around it?
Sam Bosley
@sbosley
Hi @erasmospunk, what you describes sounds like the right concept of setup, so you might need to share more details of the specific error you're seeing. but generally yes, you should create a core library that depends on squidb and squidb-annotations. then your android code depends on core and squidb-android, and your iOS code depends on core and squidb-ios.
without having any further details this is just a wild guess, but did you declare the dependencies in code using api instead of implementation? I believe that only dependencies declared with api will become part of the public api of a shared module
bhavdipb
@bhavdipb

Hi Everyone,,

I am facing one issue and not able to configure squidb with sample project also

/Users/xxxxxxxx/Downloads/squidb-master/squidb-ios/src/com/yahoo/android/sqlite/SQLiteDatatypeMismatchException.java:19: cannot find symbol
symbol: class SQLiteException
Please let me know
Abdul Wadood
@abdulwd
Hi, I just want to know if squidb performs queries on background thread by default or not on Android. Thanks!
MFlisar
@MFlisar
Currently still using squidb v3, but I have one suggestion: I like to split up my projects in modules for android and I always create a db module. I would like to hide all squidb code in there, but I have a problem. If I define public interfaces in my core module and want to expose setters, I always need to define setters with the return type of TableModel. Would it be possible to disable this queuing supporting setters and instead only create setters with void return types? This way, I would not need to write extra setters to hide the complete squidb classes within one module nor to write extra setters with void return value...
MFlisar
@MFlisar
I solved this by simply building squidb from source and adjust the BasicPropertyGenerator accordingly...
Sam Bosley
@sbosley
@MFlisar
No easy wa
No easy way without a plugin, but what about defining your interface to use a return type that’s your interface instead of TableModel? I would think that would work since the return type of the setters should be the actual class type
@abdulwd
No, queries and other db ops are synchronous. Threading choice is left up to the caller — you could use async tasks, thread pools, rx, whatever makes most sense for your app
MFlisar
@MFlisar
@sbosley totally correct, but if you're using kotlin and define interface variables like var data1: String you will get void setters/getters, using custom return types means extra work on this side, but still you're right
Additionally, kotlin is not yet supported by yur processor, is it? E.g. static function are defined in a companion object in kotlin. If I defineModelMethods there, those are not converted to class functions correctly... Can try this again, if you want to know the concrete problem (I think it was that those methods stayed static methods...)
MFlisar
@MFlisar
I would have some suggestion for a very useful plugin: I think it makes sense to hide database code in a module (in android) or in some other private package e.g. so that the final implementation is hidden from the code that uses the database classes. Would it be possible to enable generating interfaces for each data model? This would be very handy for this use case...
Sam Bosley
@sbosley
@MFlisar as to your first question, that's correct, there's nothing in the processor (or any part of squidb, really) that does anything special for kotlin. as to your second question, sure, you could write a plugin that used the declareAdditionalJava hook to generate an entirely new file based on the properties in the model spec. I'm not sure that I see too much value in this though -- an interface abstracts away implementation details so that multiple different implementations can be provided. in this case, there would be a 1-1 correspondence between the interface and its implementation, since a squidb model is really just a data transfer class. any alternative implementation wouldn't be accepted by the squidb database classes (since it expects AbstractModel etc.)
plus, the interface would be tightly coupled to the processor generating it, so it wouldn't be of much help in abstracting away data models for switching to other data layers either
or maybe you have some use case in mind I haven't thought of?
MFlisar
@MFlisar
My main purpose of the interface abstraction is modularisation and compile time optimisation. Writing a database module, then generating the interface in a minimal core module und using the interface in the ui and some other modules has the big advantage, that non of my other modules have any dependency on any database code... E.g. I have a highly customisable app with hundreds of settings, I have a ui module, a settings module, a image loading module and all of them use the common data interfaces... Second good thing here is, that annotation processors are slowing down compile time as well, moving them to small modules that don't change often can improve compile time as well...
Secondly, is kotlin support planned? I use extension functions that only work in kotlin, so kotlin support would be nice for me...
Sam Bosley
@sbosley
@MFlisar I don't have nearly enough kotlin expertise to be able to do anything special in the annotation processor, but according to this doc, annotation processing should "just work" in most cases. which makes sense, it's really the responsibility of the compiler to present to the annotation processor a consistent view into the code being compiled. the annotation processor is very limited by what the compiler provides to it. you mentioned some kind of issue with static methods in companion objects; did you annotate them with @JvmStatic as is documented there?
MFlisar
@MFlisar
You're right. I will test the annotation. Thanks