Persistência Com Realm
Total Page:16
File Type:pdf, Size:1020Kb
Armazenamento Persistente com Realm Prof. Fellipe Aleixo ([email protected]) Banco de Dados Realm • Alternativa open source ao uso do SQLite – Boa performance e facilidade de usar • Instalação via npm • Pré-requisitos: – Pode endereçar as plataformas Android e iOS – React Native 0.31.0 e posterior é suportado Instalação • Criar um novo projeto React Native: – react-native init <project-name> • No diretório do projeto: – npm install --save realm • Vincular o projeto ao módulo Realm – react-native link realm Introdução • Realm Javascript funciona tanto com React Native quanto com Node.js • Exemplo: const Realm = require('realm'); // Define your models and their properties const CarSchema = { name: 'Car', properties: { make: 'string', model: 'string', miles: {type: 'int', default: 0}, } }; const PersonSchema = { name: 'Person', properties: { name: 'string', birthday: 'date', cars: 'Car[]', picture: 'data?' // optional property } }; Realm.open({schema: [CarSchema, PersonSchema]}) .then(realm => { // Create Realm objects and write to local storage realm.write(() => { const myCar = realm.create('Car', { make: 'Honda', model: 'Civic', miles: 1000, }); myCar.miles += 20; // Update a property value }); // Query Realm for all cars with a high mileage const cars= realm.objects('Car').filtered('miles > 1000'); // Will return a Results object with our 1 car cars.length // => 1 // Add another car realm.write(() => { const myCar = realm.create('Car', { make: 'Ford', model: 'Focus', miles: 2000, }); }); // Query results are updated in realtime cars.length // => 2 }) .catch(error => { console.log(error); }); Introdução • Exemplos podem ser encontrados no GitHub – Repositório realm-js https://github.com/realm/realm-js/tree/master/examples • Realm Studio – Plataforma para o gerenciamento de bancos de dados Realm – https://realm.io/products/realm-studio/ Configurando uma Aplicação • Método estático open da classe Realm – Passando um objeto de configuração // Get the default Realm with support for our objects Realm.open({schema: [Car, Person]}) .then(realm => { // ...use the realm instance here }) .catch(error => { // Handle the error here if something went wrong }); Configurando uma Aplicação • Elementos do objeto de configuração – schema – tabelas do banco – path – caminho para outro Realm – migration – função de migração – sync – objeto sync para acesso sincronizado – inMemory – objetos carregados na memória – deleteRealmIfMigrationNeeded – apaga o banco, caso seja necessária a realização de uma migração • https://realm.io/docs/javascript/latest/api/Realm.html#~Configuration Versão do Banco • Propriedade schemaVersion const PersonSchema = { name: 'Person', properties: { name: 'string' } }; // schemaVersion defaults to 0 Realm.open({schema: [PersonSchema]}); – Definida em caso de atualização do banco Versão do Banco const UpdatedPersonSchema = { // The schema name is the same, so previous `Person` object // in the Realm will be updated name: 'Person', properties: { name: 'string', dog: 'Dog' // new property } }; // this will throw because the schema has changed // and `schemaVersion` is not specified Realm.open({schema: [UpdatedPersonSchema]}); // this will succeed and update the Realm to the new schema Realm.open({schema: [UpdatedPersonSchema], schemaVersion: 1}); Modelos • Os modelos (de dados) são definidos pela propriedade schema na inicialização do Realm – Consiste no nome do modelo (name) e – Uma lista de propriedades (properties) Modelos const Realm = require('realm'); const CarSchema = { name: 'Car', properties: { make: 'string', model: 'string', miles: {type: 'int', default: 0}, } }; Modelos const PersonSchema = { name: 'Person', properties: { name: 'string', birthday: 'date', cars: 'Car[]' picture: 'data?', // optional property } }; // Initialize a Realm with Car and Person models Realm.open({schema: [CarSchema, PersonSchema]}) .then(realm => { // ... use the realm instance to read and modify data }) Classes de Modelo • Podem ser utilizadas classes – Necessário definir o esquema no construtor class Person { get fullName() { return this.firstName + ' ' + this.lastName; } } Person.schema = { name: 'Person', properties: { firstName: 'string', lastName: 'string' } }; Classes de Modelo • Dessa forma, a classe pode ser passada para a propriedade schema na configuração Realm.open({schema: [Person]}) .then( /* ... */ ); – As propriedades são acessadas normalmente realm.write(() => { const john = realm.create('Person', { firstName: 'John', lastName: 'Smith' }); john.lastName = 'Peterson'; console.log(john.fullName); // -> 'John Peterson' }); Tipos Suportados • bool: valores booleanos JavaScript • int, float e double: valores numéricos JavaScript. ‘int’ e ‘double’ são armazenados em 64 bits, enquanto ‘float’ em 32 bits • string: valores de texto • data: mapeados em ArrayBuffer • date: mapeados em Date Tipos Suportados const CarSchema = { name: 'Car', properties: { // The following property types are equivalent make: {type: 'string'}, model: 'string', } } Propriedades Opcionais • Por padrão os tipos básicos são obrigatórios const PersonSchema = { name: 'Person', properties: { realName: 'string', // required property displayName: 'string?', // optional property birthday: {type: 'date', optional: true}, // optional } }; let realm = new Realm({schema: [PersonSchema, CarSchema]}); Propriedades Opcionais realm.write(() => { // optional properties can be set to null or undefined let charlie = realm.create('Person', { realName: 'Charlie', displayName: null, // could also be omitted entirely birthday: new Date(1995, 11, 25), }); // optional properties can be set to `null`, `undefined`, // or to a new non-null value charlie.birthday = undefined; charlie.displayName = 'Charles'; // Setting a non-optional to null will throw `TypeError` // charlie.realName = null; }); Propriedades de Lista const PersonSchema = { name: 'Person', properties: { name: 'string', testScores: 'double?[]' } }; let realm = new Realm({schema: [PersonSchema, CarSchema]}); realm.write(() => { let charlie = realm.create('Person', { name: 'Charlie', testScores: [100.0] }); // Charlie had an absense for the second test charlie.testScores.push(null); // And then he didn't do so well on the third test charlie.testScores.push(70.0); }); Chave Primária • Definida através da propriedade primaryKey – Referenciando propriedades do tipo string ou int const BookSchema = { name: 'Book', primaryKey: 'id', properties: { id: 'int', // primary key title: 'string', price: 'float' } }; RELACIONAMENTOS Relacionamentos To-One • Podem ser referenciados outros esquemas como tipo de uma propriedade const PersonSchema = { name: 'Person', properties: { // The following property definitions are equivalent car: {type: 'Car'}, van: 'Car', } }; // CarSchema is needed since contains properties of type 'Car' Realm.open({schema: [CarSchema, PersonSchema]}) .then(/* ... */); Relacionamentos To-One • Ao acessar propriedades que referenciam outros esquemas a sintaxe é normal realm.write(() => { const nameString = person.car.name; person.car.miles = 1100; // create a new Car by setting the property to an object // with all of the required fields person.van = {make: 'Ford', model: 'Transit'}; // set both properties to the same car instance person.car = person.van; }); Relacionamentos To-Many • Semelhante às propriedades básicas, pode ser referenciada uma lista de objetos const PersonSchema = { name: 'Person', properties: { // The following property definitions are equivalent cars: {type: 'list', objectType: 'Car'}, vans: 'Car[]' } } let carList = person.cars; Relacionamentos To-Many • Semelhante às propriedades básicas, pode ser referenciada uma lista de objetos // Add new cars to the list realm.write(() => { carList.push({make: 'Honda', model: 'Accord', miles: 100}); carList.push({make: 'Toyota', model: 'Prius', miles: 200}); }); let secondCar = carList[1].model; // access using an array index Relacionamentos Inversos • Os links são unidirecionais • Ex. são propriedades independentes: – propriedade To-Many – Person.dogs – propriedade To-One – Dog.owner à Person • Definição de uma propriedade do tipo linkingObjects Relacionamentos Inversos const PersonSchema = { name: 'Person', properties: { dogs: 'Dog[]' } } const DogSchema = { name:'Dog', properties: { // No shorthand syntax for linkingObjects properties owners: {type: 'linkingObjects’, objectType: 'Person’, property: 'dogs'} } } Relacionamentos Inversos const ShipSchema = { name: 'Ship', properties: { captain: 'Captain' } } const CaptainSchema = { name: 'Captain', properties: { ships: {type: 'linkingObjects’, objectType: 'Ship’, property: 'captain'} } } MANIPULAÇÃO E CONSULTAS Manipulação de Objetos • Criação, atualização e remoção de objetos no Realm acontecem em um bloco de transação write() • Criando objetos: try { realm.write(() => { realm.create('Car', {make: 'Honda’, model: 'Accord’, drive: 'awd'}); }); } catch (e) { console.log("Error on creation"); } Manipulação de Objetos • Atualizando objetos: realm.write(() => { car.miles = 1100; }); – Referenciando um objeto através da chave realm.write(() => { // Create a book object realm.create('Book', {id: 1, title: 'Recipes', price: 35}); // Update book with new price keyed off the id realm.create('Book', {id: 1, price: 55}, true); }); Manipulação de Objetos • Removendo objetos: realm.write(() => { // Create a book object let book = realm.create('Book', {id: 1, title: 'Recipes’, price: 35}); // Delete the book realm.delete(book); // Delete multiple books by passing in a `Results`, `List`, // or JavaScript