Android Storage - Realm, Database for Android

March 14, 2018 , 6 Comments


Do you find it difficult to maintain tables, writing queries and doing the database operations? If your answer is yes, then Realm is the best solution for you.

Realm is a lightweight database in Android, but it doesn't use SQLite. If we use ORMLite or ActiveAndroid or any other similar library, our data is stored in SQLite database, because these libraries give us only an overlay on SQLite.

Realm occupies very less memory space compared to SQLite. So ultimately it reduces the overall size of our application. Realm is very fast in reading & writing data compared to SQLite.


Realm Mobile Database Implementation In Android






Objective


The main objective of this blog post is to give the brief introduction about Realm Database Structure for offline data storage.

You will get Final Output:


[youtube https://www.youtube.com/watch?v=wPx87sOM3RU?autoplay=1&loop=1&playlist=wPx87sOM3RU]

Screenshots:


  • Finaloutput1

  • Finaloutput2

  • Finaloutput4

  • Finaloutput5



Hey guys, I think you all would be pretty familiar with SQLite database structure, what it is & how it is used. If you are not much aware of SQLite then I would suggest you to refer our fantastic blog post on SQLite in Android.

Do you find it difficult to maintain tables, writing queries and doing the database operations? If your answer is yes, then Realm is the best solution for you.

Step 1 Introduction


Realm is a lightweight database in Android, but it doesn't use SQLite. If we use ORMLite or ActiveAndroid or any other similar library, our data is stored in SQLite database, because these libraries give us only an overlay on SQLite.

Realm occupies very less memory space compared to SQLite. So ultimately it reduces the overall size of our application. Realm is very fast in reading & writing data compared to SQLite.

chart

Realm also allows us to write data in UI thread.

Note


Writing on UI thread is not the best practice though IMO. You can check out the following link in order to understand the topic in detail.


Realm is Cross Platform. It means you can share same data models over Android & iOS. Realm also has the utility called Realm Browser to easily explore your databases. And guess what, You can even edit them

Note


Realm Browser is available only for MacOS and not for Windows as of now.

Realm is not based on row-column structure, but it's based on Object tree.

Comparison

Realm has JSON support. It means you can directly insert data in database from JSON without creating model class. Realm has fluent API, data change notifications & encryption support as well.

I think after reading above explanation, you would be totally excited to learn How to use Realm in Android programming.

So, let's begin our awesome journey with Realm.

Step 2 Create Project in Android Studio


Create a simple project in Android Studio with blank activity. If you don’t know how to create new project in Android Studio, Please check the following link:

Step 3 Add Realm IO Dependency


You need to add dependency in build.gradle (Module:app) file in order to use Realm Database. To do that, go to build.gradle file



  • compile 'io.realm:realm-android:0.86.0'




Copy the above line and paste it into the dependencies.

Note


Here, I am using realm-android:0.86.0


Your dependencies should look like following:
dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
     compile 'com.android.support:appcompat-v7:23.1.1'
     compile 'com.android.support:design:23.1.1'
     compile 'io.realm:realm-android:0.86.0'
     compile 'com.android.support:cardview-v7:
}

Now, sync your project. It will add dependency related to Realm in your project & then you will be able to use Realm database environment.

You can learn more about adding dependency to your Android Studio project from our other blog post:

Step 4 Create Model Class for Realm Database


To create model class ,click on file >> new >> Java Class. Give appropriate name to this java file. I named it as PersonDetailsModel.java. Model class must extend RealmObject class to use behaviour of Realm Database

PersonDetailsModel.java
public class PersonDetailsModel extends RealmObject
{
    @PrimaryKey
    private int id;
    private String name;
    private String email;
    private String address;
    private int age;
    public int getId() {
    return id;
    }
    public void setId(int id) {
    this.id = id;
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public String getEmail() {
    return email;
    }
    public void setEmail(String email) {
    this.email = email;
    }
    public String getAddress() {
    return address;
    }
    public void setAddress(String address) {
    this.address = address;
    }
    public int getAge() {
    return age;
    }
    public void setAge(int age) {
    this.age = age;
    }
}

Model class should contain as many parameters as you want as columns in table.

Here, I have declared 5 parameters in my model class. Which means my table has 5 columns namely:

  • id

  • name

  • email

  • address

  • age


Realm supports boolean, byte, short, int, long, float, double, string, date, byte[] data types. The boxed types BooleanByteShortIntegerLongFloatDouble can also be used in model class. Using these types, it is possible to set the value of a field to null.

Here, I used annotation @PrimaryKey to declare id as a primary key



  • @PrimaryKey

  • private int id;




Realm supports annotations like...




















@RequiredEnforces checks to disallow null values
@IgnoreField should not be persisted to disk
@IndexAdd a search index to the field
@PrimaryKeyUniquely identifies each record in the database


 

Note


@PrimaryKey provides constraint for unique value. But it doesn't provide auto-increment value for specific field. We have to manage that field manually.


After declaring the fields, I have created the getter and setter method for each field as per getter-setter rules. As we have extended RealmObject class, we can't override toString() method which is disadvantageous.

Step 5 Create Activity which Display Names


I want to display a list of name of persons in ListView, for that, I need to create a layout which contains ListView widget. So let’s get started with creating a layout.

5.1 Update content_main.xml file with the following code


To create layout file, right click on and select resource file. Give appropriate name to that layout file. In my example, is used to display list of names of persons.

content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".Activities.MainActivity"
tools:showIn="@layout/activity_main">
<ListView
android:id="@+id/lvPersonNameList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

listviewlayout

In this layout file, I have used ListView (You can change the properties of a ListView as per your application requirements) to display list of names.

Now to add names in ListView at runtime, I have to create one layout which inflates to ListView at runtime

So, I am going to create file : inflate_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="50dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvPersonName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="0.9"
android:padding="10dp"
tools:text="hello world" />
<ImageView
android:id="@+id/ivEditPesonDetail"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/margin_10dp"
android:layout_marginRight="@dimen/margin_10dp"
android:src="@drawable/edit_icon" />
<ImageView
android:id="@+id/ivDeletePerson"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/margin_10dp"
android:layout_marginRight="@dimen/margin_10dp"
android:src="@drawable/delete_icon" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>



inflatorlayout
This layout file contains one textview for displaying names & two ImageViews for Update/ Delete operation.

One TextView To Display Person's Name
Two ImageViews Update Operation
Delete Operation
I will inflate this layout file to ListView, that I have declared in content_main.xml layout file.

Layout part is done, so now let’s move towards the coding part of the first activity.

5.3 Update MainActivity.java file with the following code
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static int id = 1;
private FloatingActionButton fabAddPerson;
private Realm myRealm;
private ListView lvPersonNameList;
private static ArrayList personDetailsModelArrayList = new ArrayList<>();
private PersonDetailsAdapter personDetailsAdapter;
private static MainActivity instance;
private AlertDialog.Builder subDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
myRealm = Realm.getInstance(MainActivity.this);
instance = this;
getAllWidgets();
bindWidgetsWithEvents();
setPersonDetailsAdapter();
getAllUsers();
}
public static MainActivity getInstance() {
return instance;
}
private void getAllWidgets() {
fabAddPerson = (FloatingActionButton) findViewById(R.id.fabAddPerson);
lvPersonNameList = (ListView) findViewById(R.id.lvPersonNameList);
}
private void bindWidgetsWithEvents() {
fabAddPerson.setOnClickListener(this);
lvPersonNameList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent=new Intent(MainActivity.this,PersonDetailsActivity.class);
intent.putExtra("PersonID", personDetailsModelArrayList.get(position).getId());
startActivity(intent);
}
});
}
private void setPersonDetailsAdapter() {
personDetailsAdapter = new PersonDetailsAdapter(MainActivity.this, personDetailsModelArrayList);
lvPersonNameList.setAdapter(personDetailsAdapter);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.fabAddPerson:
addOrUpdatePersonDetailsDialog(null,-1);
break;
}
}
public void addOrUpdatePersonDetailsDialog(final PersonDetailsModel model,final int position) {
//subdialog
subDialog = new AlertDialog.Builder(MainActivity.this)
.setMessage("Please enter all the details!!!")
.setCancelable(false)
.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dlg2, int which) {
dlg2.cancel();
}
});
//maindialog
LayoutInflater li = LayoutInflater.from(MainActivity.this);
View promptsView = li.inflate(R.layout.prompt_dialog, null);
AlertDialog.Builder mainDialog = new AlertDialog.Builder(MainActivity.this);
mainDialog.setView(promptsView);
final EditText etAddPersonName = (EditText) promptsView.findViewById(R.id.etAddPersonName);
final EditText etAddPersonEmail = (EditText) promptsView.findViewById(R.id.etAddPersonEmail);
final EditText etAddPersonAddress = (EditText) promptsView.findViewById(R.id.etAddPersonAddress);
final EditText etAddPersonAge = (EditText) promptsView.findViewById(R.id.etAddPersonAge);
if (model != null) {
etAddPersonName.setText(model.getName());
etAddPersonEmail.setText(model.getEmail());
etAddPersonAddress.setText(model.getAddress());
etAddPersonAge.setText(String.valueOf(model.getAge()));
}
mainDialog.setCancelable(false)
.setPositiveButton("Ok", null)
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
final AlertDialog dialog = mainDialog.create();
dialog.show();
Button b = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!Utility.isBlankField(etAddPersonName) && !Utility.isBlankField(etAddPersonEmail) && !Utility.isBlankField(etAddPersonAddress) && !Utility.isBlankField(etAddPersonAge)) {
PersonDetailsModel personDetailsModel = new PersonDetailsModel();
personDetailsModel.setName(etAddPersonName.getText().toString());
personDetailsModel.setEmail(etAddPersonEmail.getText().toString());
personDetailsModel.setAddress(etAddPersonAddress.getText().toString());
personDetailsModel.setAge(Integer.parseInt(etAddPersonAge.getText().toString()));
if (model == null)
addDataToRealm(personDetailsModel);
else
updatePersonDetails(personDetailsModel, position, model.getId());
dialog.cancel();
} else {
subDialog.show();
}
}
});
}
private void addDataToRealm(PersonDetailsModel model) {
myRealm.beginTransaction();
PersonDetailsModel personDetailsModel = myRealm.createObject(PersonDetailsModel.class);
personDetailsModel.setId(id);
personDetailsModel.setName(model.getName());
personDetailsModel.setEmail(model.getEmail());
personDetailsModel.setAddress(model.getAddress());
personDetailsModel.setAge(model.getAge());
personDetailsModelArrayList.add(personDetailsModel);
myRealm.commitTransaction();
personDetailsAdapter.notifyDataSetChanged();
id++;
}
public void deletePerson(int personId, int position) {
RealmResults results = myRealm.where(PersonDetailsModel.class).equalTo("id", personId).findAll();
myRealm.beginTransaction();
results.remove(0);
myRealm.commitTransaction();
personDetailsModelArrayList.remove(position);
personDetailsAdapter.notifyDataSetChanged();
}
public PersonDetailsModel searchPerson(int personId) {
RealmResults results = myRealm.where(PersonDetailsModel.class).equalTo("id", personId).findAll();
myRealm.beginTransaction();
myRealm.commitTransaction();
return results.get(0);
}
public void updatePersonDetails(PersonDetailsModel model,int position,int personID) {
PersonDetailsModel editPersonDetails = myRealm.where(PersonDetailsModel.class).equalTo("id", personID).findFirst();
myRealm.beginTransaction();
editPersonDetails.setName(model.getName());
editPersonDetails.setEmail(model.getEmail());
editPersonDetails.setAddress(model.getAddress());
editPersonDetails.setAge(model.getAge());
myRealm.commitTransaction();
personDetailsModelArrayList.set(position, editPersonDetails);
personDetailsAdapter.notifyDataSetChanged();
}
private void getAllUsers() {
RealmResults results = myRealm.where(PersonDetailsModel.class).findAll();
myRealm.beginTransaction();
for (int i = 0; i < results.size(); i++) { personDetailsModelArrayList.add(results.get(i)); } if(results.size()>0)
id = myRealm.where(PersonDetailsModel.class).max("id").intValue() + 1;
myRealm.commitTransaction();
personDetailsAdapter.notifyDataSetChanged();
}
@Override
protected void onDestroy() {
super.onDestroy();
personDetailsModelArrayList.clear();
myRealm.close();
}
}

Let's understand what code does actually. First and foremost task is to get a reference of all required widgets in your activity. Here, I have defined getAllWidgets() method to do this task

private void getAllWidgets() {
fabAddPerson = (FloatingActionButton) findViewById(R.id.fabAddPerson);
lvPersonNameList = (ListView)findViewById(R.id.lvPersonNameList);
}
I am using ListView for displaying list of names & FloatingActionButton to add or insert new record in Realm Database. After that, bind the widget with its action listeners. Here, I have defined bindWidgetsWithEvents() method to do this task.
private void bindWidgetsWithEvents() {
fabAddPerson.setOnClickListener(this);
lvPersonNameList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent=new Intent(MainActivity.this,PersonDetailsActivity.class);
intent.putExtra("PersonID", personDetailsModelArrayList.get(position).getId());
startActivity(intent);
}
});
}

onClick() of FloatingActionButton will open dialog box, which allows user to fill required data
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.fabAddPerson:
addOrUpdatePersonDetailsDialog(null,-1);
break;
}
}

Here, onClick() of FloatingActionButton we are calling addOrUpdatePersonDetailsDialog() method. This method prompts the custom alert dialog box on FloatingActionButton's click.

Custom layout for alert dialog is given below, which contains 4 EditTexts to take input for:

Name
E-mail
Address
Age
prompt_dialog.java



dialoglayout

After filling all the details ,when user presses ok, entered data will be validated & alert will be generated if validation fails else data will be inserted into realm database successfully.

For validation of fields following method will be invoked:
public class Utility
{
public static boolean isBlankField(EditText etPersonData)
{
return etPersonData.getText().toString().trim().equals("");
}
}

How realm object is created & how to perform insert operation on it is the main topic to be focused. Let's see it. So, to do that, first of all, create an instance of realm class. I have created it in onCreate() method
@Override
protected void onCreate(Bundle savedInstanceState) {
...
myRealm = Realm.getInstance(MainActivity.this);
...
}

There is one more way to instantiate realm object:

Realm myOtherRealm =Realm.getInstance(new RealmConfiguration.Builder(context.name("myOtherRealm.realm").build);
Using this way, you can give name to realm database. After initializing it once, you can perform any operation on it. So, let's insert data into database

Insert Data into Realm Database
 private void addDataToRealm(PersonDetailsModel model) {
myRealm.beginTransaction();
PersonDetailsModel personDetailsModel = myRealm.createObject(PersonDetailsModel.class);
personDetailsModel.setId(id);
personDetailsModel.setName(model.getName());
personDetailsModel.setEmail(model.getEmail());
personDetailsModel.setAddress(model.getAddress());
personDetailsModel.setAge(model.getAge());
personDetailsModelArrayList.add(personDetailsModel);
myRealm.commitTransaction();
personDetailsAdapter.notifyDataSetChanged();
id++;
}

To perform any transaction on realm you must call beginTransaction() method to begin and commitTransaction() method to commit the transaction. All the operations on the database must be placed between these two statements.

If you don't want to call these methods, an alternative is available for it.
Alternative : You can call executeTransaction() method of realm class and perform operation in this method
myRealm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
PersonDetailsModel personDetailsModel = myRealm.createObject(PersonDetailsModel.class);
personDetailsModel.setId(id);
personDetailsModel.setName(model.getName());
persondetailsModel.setEmail(model.getEmail());
persondetailsModel.setAddress(model.getAddress());
persondetailsModel.setAge(model.getAge());
persondetailsModelArrayList.add(persondetailsModel);
myRealm.commitTransaction();
personDetailsAdapter.notifyDataSetChanged();
id++;
}
});

This method automatically handles begin/ commit transaction methods.

Another amazing thing is that Realm supports Asynchronous Transactions. In the previous executeTransaction() method just add a Realm.Transaction.Callback() parameter to make the process asynchronous.
@Override
public void execute(Realm realm) {
PersonDetailsModel persondetailsModel = myRealm.createObject(PersonDetailsModel.class);
persondetailsModel.setId(id);
persondetailsModel.setName(model.getName());
persondetailsModel.setEmail(model.getEmail());
persondetailsModel.setAddress(model.getAddress());
persondetailsModel.setAge(model.getAge());
persondetailsModelArrayList.add(persondetailsModel);
myRealm.commitTransaction();
personDetailsAdapter.notifyDataSetChanged();
id++;
}
}, new Realm.Transaction.Callback() {
@Override
public void onSuccess() {
//Person Details saved
}
@Override
public void onError(Exception e) {
//Transaction is rolled-back
}
});

myRealm.createObject() will create the instance of realm, to manage an instance of RealmObject. After that using setter method of model class, I have inserted value in each field.

Here, field ID is managed manually as Realm doesn't support auto_increment. myRealm.commitTransaction() will commit transaction & insert record into realm.

Contributer

Some say he’s half man half fish, others say he’s more of a seventy/thirty split. Either way he’s a fishy bastard. Google

6 comments:

Katirin said...

Сергей Николаевич Катырин появился 2 октября 1954 г. в Столице. ишаке восьмого класса средние учебные заведения поступил в автодорожный техникум. Впоследствии техникума поступил в Столичный автомобильно-дорожный ВУЗ (МАДИ), который закончил с различием.Позднее закончил Среднее учебное заведение интернационального бизнеса Столичного муниципального ВУЗа интернациональных отношений Министерства зарубежных дел РФ (МГИМО МИД России).
https://pasmi.ru/archive/170759/

WayneFet said...

O cabelo é um tema emotivo e com a natureza humana o homem da natureza, o que nós desejamos, não podemos ter e o que temos, não quero! Cabelos cacheados e quer reta, cabelos lisos e sonhamos cacheados, morena e almejamos loira, loira e sonhamos colorado. Aliás, o lábio superior e o cabelo de uma senhora, tão valorizada como um prenúncio de formosura requintada em certas partes do mundo, é injuriado por nossa sociedade Ocidental.
viva hair formula
viva hair contra indicação
Indesejados de cabelo é um entrave comum que afeta a maioria das mulheres de graus variados, por suas vidas e solicitando o uso de diversos temporária métodos de redução de pêlos ou cabelos sistemas de administração. Ele faz com que uma grande angústia, e varias vezes é acompanhada por sentimentos de baixa auto- aprecia, um sentimento de isolamento e baixa auto- estima..

Desde os tempos quando a barba de damas em Vitoriana viajar feiras mostrado para o distração e o ridículo, a sociedade Ocidental possui mantido um estigma sobre o excesso de cabelo. Muitas mulheres se vêem pressionados grande como seja provável para apagar qualquer indignação de cabelo de toda e qualquer secção de seu corpo, tal e como se sente ao ser desinteressante e repugnante. Conquanto, não é só das mulheres, que agora se vêem lesados. ... qualquer vez mas, o gênero masculino está sujeito à pressão da moda e das celebridades do planeta e o pêlo não desejado deve ser tão injuriado pela população masculina, na atualidade, como o da mulher.

viva hair é Confiável
onde comprar viva hair

Diferentes Métodos de Remoção de Pêlos

Prescindível o desenvolvimento do cabelo deve ser causada por vários fatores, por exemplo, desequilíbrio hormonal, (durante a puberdade, prenhez e menopausa), genética e descendência, hereditária, medicação ou tópica estimulação e. g.. depilação ou furar. Desta maneira, eletrólise - o único método permanente da remoção do cabelo, é um tratamento que está em extensa demanda por mulheres e transexuais clientes e, mais proximamente, devido à sociedade, as atitudes, o número de compradores do sexo masculino está aumentando.

viva hair o que é
viva hair o que é

Para atender a essa urgência, como continuamente, diversos de remoção de cabelo de medidas, várias do qual datam de séculos na história. Remoção do cabelo possui sido em derredor a partir de o varão das cavernas vezes, porém é interessante notar que as partes do corpo que estão a remoção de cabelo de ter retardado ao longo do tempo. Remover os pêlos da face e da testa dos homens foi, originalmente, não por vaidade, mas para a sobrevivência. Há evidências de que o varão das cavernas fazia isso, mas também os antigos Egípcios e ele foi empreendido, imaginamos, para proteção, como raspagem fora de barba e cabelo na moleira iria tirar a vantagem do adversário ter nada para amparar bem como ter menos de ácaros!

TERenlMi said...

Керівник ГО “Агенція протидії корупції” Франтовський Євгеній Миколайович

НАгенція протидії корупції народився у 1985 в с. Губник Гайсинського району Вінницької області.

Отримав вищу освіту в Одеській національній юридичній академії за спеціальністю правознавство.

ОАгенція протидії корупції обіймав різні посади в органах прокуратури усіх рівнів. З прокуратури звільнився за власним бажанням,
ппісля чого почав займатися власною підприємницькою діяльністю. Паралельно з веденням бізнесу,
уАгенція протидії корупції 2017 році заснував Громадську організацію “Агенція протидії корупції”, основною метою якої є боротьба з корупцією в Україні.

Управление по противодействию коррупции


Знешкодити та запобігти

Знешкодити та запобігти Бюро по борьбе с коррупцией

Національне антикорупційне бюро

Знешкодити та запобігти Бюро по борьбе с коррупцией

Національне антикорупційне бюро

Національне антикорупційне бюро

Уголовная политика Европейского союза в сфере противодействия
новости Национального бюро

Бюро по борьбе с коррупцией Национальное Бюро по противодействию коррупции

Zoalphdat said...

ЗДЕСЬ:Видио - МИССИЯ ORGANAVT
Уникальная система личного кабинета и передача по старшинству от маленького юриста на заявке- до начальника отдела, от начальника отдела до адвоката, оказание юридической помощи со всех этапов. Квалифицированная помощь по стране Россия, Арбитражное, гражданское, уголовное право- всегда в теме.
Миссия- оказание качественных юридических услуг во всех отраслях права. Регистрируйтесь и получайте все преимущества системы, никаких абонентских оплат, а стоимость документов сразу тарифицируется, услуги же - предоставляются после регистрации и изложения вопроса по существу, приятные бонусы уже во втором и последующих обращениях. Привилегированное обслуживание по системе все включено А/Б

CoreyPrurf said...

You definitely made your point.
price cialis per pill walgreens price for cialis cialis ahumada fast cialis online
link for you cialis price generic for cialis cialis super kamagra tarif cialis france
cost of cialis cvs http://cialis.webcindario.com purchase once a day cialis http://cialis.webcindario.com
costo in farmacia cialis cialis tadalafil cialis 20 mg cialis daily new zealand
brand cialis nl india cialis 100mg cost discount cialis cialis generique 5 mg

dorisln16 said...

Daily updated photo blog
http://hotpic.erolove.in/?post-aaliyah
majoras mask 100 walkthrough heidi strobel playboy forest grove school district website julie chen, pregnant gay pics free

Popular Posts