Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
com.pushtorefresh.storio:sqlite-annotations
Advanced tools
Modern API for SQLiteDatabase and ContentResolver
Put
, Get
, Delete
null
in queriesCursor
and ContentValues
you don't have toStorIO
is not ORMStorIO
can be executed as blocking call or as rx.Observable
/rx.Single
/rx.Completable
RxJava
as first class citizen, but it's not required dependency!rx.Observable
from Get
Operation will observe changes in StorIO
(SQLite
or ContentProvider
) and receive updates automaticallyStorIO
is replacements for SQLiteDatabase
and ContentResolver
APIsStorIO
+ RxJava
is replacement for Loaders
APIMockStorIO
(similar to MockWebServer) for easy unit testingPut
, Get
, Delete
-> less bugsStorIO
annotated with @NonNull
and @Nullable
annotations -> less bugsStorIO
has unit and integration tests -> less bugsEasy ways to learn how to use StorIO
-> check out Documentation
, Design Tests
and Sample App
:
// If you need StorIO for SQLite
compile 'com.pushtorefresh.storio:sqlite:1.13.0'
// If you need StorIO for ContentResolver
compile 'com.pushtorefresh.storio:content-resolver:1.13.0'
// IN StorIO 2.0 we will remove default Scheduling from Rx Operations!
// You'll have to put subscribeOn() manually!
// Notice that RxJava is optional dependency for StorIO,
// So if you need it -> please add it manually.
You can find all releases on Maven Central.
List<Tweet> tweets = storIOSQLite
.get()
.listOfObjects(Tweet.class) // Type safety
.withQuery(Query.builder() // Query builder
.table("tweets")
.where("author = ?")
.whereArgs("artem_zin") // Varargs Object..., no more new String[] {"I", "am", "tired", "of", "this", "shit"}
.build()) // Query is immutable — you can save it and share without worries
.prepare() // Operation builder
.executeAsBlocking(); // Control flow is readable from top to bottom, just like with RxJava
storIOSQLite
.put() // Insert or Update
.objects(someTweets) // Type mapping!
.prepare()
.executeAsBlocking();
storIOSQLite
.delete()
.byQuery(DeleteQuery.builder()
.table("tweets")
.where("timestamp <= ?")
.whereArgs(System.currentTimeMillis() - 86400) // No need to write String.valueOf()
.build())
.prepare()
.executeAsBlocking();
storIOSQLite
.get()
.listOfObjects(Tweet.class)
.withQuery(Query.builder()
.table("tweets")
.build())
.prepare()
.asRxObservable() // Get Result as rx.Observable and subscribe to further updates of tables from Query!
.observeOn(mainThread()) // All Rx operations work on Schedulers.io()
.subscribe(tweets -> { // Please don't forget to unsubscribe
// Will be called with first result and then after each change of tables from Query
// Several changes in transaction -> one notification
adapter.setData(tweets);
}
);
Cursor cursor = storIOSQLite
.get()
.cursor()
.withQuery(Query.builder() // Or RawQuery
.table("tweets")
.where("who_cares = ?")
.whereArgs("nobody")
.build())
.prepare()
.executeAsBlocking();
StorIOSQLite
or StorIOContentResolver
StorIOSQLite storIOSQLite = DefaultStorIOSQLite.builder()
.sqliteOpenHelper(someSQLiteOpenHelper)
.addTypeMapping(Tweet.class, SQLiteTypeMapping.<Tweet>builder()
.putResolver(new TweetPutResolver()) // object that knows how to perform Put Operation (insert or update)
.getResolver(new TweetGetResolver()) // object that knows how to perform Get Operation
.deleteResolver(new TweetDeleteResolver()) // object that knows how to perform Delete Operation
.build())
.addTypeMapping(...)
// other options
.build(); // This instance of StorIOSQLite will know how to work with Tweet objects
You can override Operation Resolver per each individual Operation, it can be useful for working with SQL JOIN
.
To save you from coding boilerplate classes we created Annotation Processor which will generate PutResolver
, GetResolver
and DeleteResolver
at compile time, you just need to use generated classes
Notice that annotation processors are not part of the library core, you can work with StorIO without them, we just made them to save you from boilerplate.
StorIOSQLite
:
dependencies {
compile 'com.pushtorefresh.storio:sqlite-annotations:insert-latest-version-here'
annotationProcessor 'com.pushtorefresh.storio:sqlite-annotations-processor:insert-latest-version-here'
}
StorIOContentResolver
:
dependencies {
compile 'com.pushtorefresh.storio:content-resolver-annotations:insert-latest-version-here'
annotationProcessor 'com.pushtorefresh.storio:content-resolver-annotations-processor:insert-latest-version-here'
}
@StorIOSQLiteType(table = "tweets")
public class Tweet {
// Annotated fields should have package-level visibility.
@StorIOSQLiteColumn(name = "author")
String author;
@StorIOSQLiteColumn(name = "content")
String content;
// Please leave default constructor with package-level visibility.
Tweet() {}
}
@AutoValue
@StorIOSQLiteType(table = "tweets")
public abstract class Tweet {
// Annotated methods should have package-level or public visibility.
@StorIOSQLiteColumn(name = "author")
abstract String author();
@StorIOSQLiteColumn(name = "content")
abstract String content();
// Parameters order depends on declaration order.
@StorIOSQLiteCreator
static Tweet create(String author, String content) {
return new AutoValue_Tweet(author, content)
}
}
Annotation Processor will generate three classes in same package as annotated class during compilation:
TweetStorIOSQLitePutResolver
TweetStorIOSQLiteGetResolver
TweetStorIOSQLiteDeleteResolver
You just need to apply them:
StorIOSQLite storIOSQLite = DefaultStorIOSQLite.builder()
.sqliteOpenHelper(someSQLiteOpenHelper)
.addTypeMapping(Tweet.class, SQLiteTypeMapping.<Tweet>builder()
.putResolver(new TweetStorIOSQLitePutResolver()) // object that knows how to perform Put Operation (insert or update)
.getResolver(new TweetStorIOSQLiteGetResolver()) // object that knows how to perform Get Operation
.deleteResolver(new TweetStorIOSQLiteDeleteResolver()) // object that knows how to perform Delete Operation
.build())
.addTypeMapping(...)
// other options
.build(); // This instance of StorIOSQLite will know how to work with Tweet objects
BTW: Here is a class with all types of fields, supported by StorIO SQLite Annotation Processor.
Few tips about Operation Resolvers:
API of StorIOContentResolver
is same.
Easy ways to learn how to use StorIO
-> check out Design Tests
and Sample App
:
Because StorIO works with important things like User data and so on, we use Semantic Versioning 2.0.0 scheme for releases (http://semver.org).
Short example:
1.2.3
-> MAJOR.MINOR.PATCH
MAJOR
version changes when we make incompatible API changes.MINOR
version changes when we add functionality in a backwards-compatible manner.PATCH
version changes when we make backwards-compatible bug fixes.Please read CHANGELOG
and check what part of the version has changed, before switching to new version.
StorIOSQLite
and StorIOContentResolver
— are abstractions with default implementations: DefaultStorIOSQLite
and DefaultStorIOContentResolver
.
It means, that you can have your own implementation of StorIOSQLite
and StorIOContentResolver
with custom behavior, such as memory caching, verbose logging and so on or mock implementation for unit testing (we are working on MockStorIO
).
One of the main goals of StorIO
— clean API for Humans which will be easy to use and understand, that's why StorIOSQLite
and StorIOContentResolver
have just several methods, but we understand that sometimes you need to go under the hood and StorIO
allows you to do it: StorIOSQLite.Internal
and StorIOContentResolver.Internal
encapsulates low-level methods, you can use them if you need, but please try to avoid it.
All Query
objects are immutable, you can share them safely.
####Concept of Prepared Operations
You may notice that each Operation (Get, Put, Delete) should be prepared with prepare()
. StorIO
has an entity called PreparedOperation<T>
, and you can use them to perform group execution of several Prepared Operations or provide PreparedOperation<T>
as a return type of your API (for example in Model layer) and client will decide how to execute it: executeAsBlocking()
or asRxObservable()
. Also, Prepared Operations might be useful for ORMs based on StorIO
.
You can customize behavior of every Operation via Resolvers
: GetResolver
, PutResolver
, DeleteResolver
.
Every Operation can be executed as rx.Observable
, rx.Single
or rx.Completable
. Get Operations will be automatically subscribed to the updates of the data.
Every Observable runs on Schedulers.io()
, in v2.0 we will remove default scheduling!
Made with love in Pushtorefresh.com by @artem_zin, @nikitin-da and @geralt-encore
FAQs
Modern API for SQLiteDatabase and ContentResolver
We found that com.pushtorefresh.storio:sqlite-annotations demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.