Statement of the problem

For example, we have 20 tables, each of them has its own set of columns. The problem is that we can make a selection in these tables, with all connections, sortings, filters, etc. Of course, for those who are familiar with IT, it will not be difficult to insert an SQL snippet and run it. However, in this case we had to provide a convenient service for usual users of the resource (network share).
Generally, the interface is pretty simple: we select tables, fields, drag the desired and click ‘Refresh’. Data set results will be shown in the table. If desired, you can save the resulting report or download the data.

How it works

Parameters are transmitted to the server:
  • string fields – the list of fields separated by ‘|’
  • string name – the name of the report
  • int? take – how many records to show
  • int? skip – how many are already shown in the page
Apart from this, we should find out what kind of relationships is shown between the selected fields. For this purpose, we have created a separate table in the database, which stores information about the tables: what type of relation to use, what basic filter is required (for example, show active users only), sorting, etc.
As a result, when appending the customer data with the data about the table in the database, we have a ReportDetail instance, which displays all the information about the field:
[[code]]czoxMzY0OlwiPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnB1YmxpYzwvc3Bhbj4gPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPntbJiomXX1jbGFzczwvc3Bhbj4gPHNwYW4gY2xhc3M9XFxcImhsLXRpdGxlXFxcIj5SZXBvcnREZXRhaWw8L3NwYW4+IHsNCiAgICA8c3BhbiBjbGFzc3tbJiomXX09XFxcImhsLWtleXdvcmRcXFwiPnB1YmxpYzwvc3Bhbj4gPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnN0cmluZzwvc3Bhbj4gRmllbGR7WyYqJl19TmFtZTsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+cHVibGljPC9zcGFuPiA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZHtbJiomXX1cXFwiPnN0cmluZzwvc3Bhbj4gVGFibGVOYW1lOw0KICAgIDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5wdWJsaWM8L3NwYW4+IDxze1smKiZdfXBhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+c3RyaW5nPC9zcGFuPiBTdWJxdWVyeTsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d297WyYqJl19cmRcXFwiPnB1YmxpYzwvc3Bhbj4gU3lzdGVtLk51bGxhYmxlJmx0OzxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5pbnQ8L3NwYW4+JntbJiomXX1ndDsgRGlzcGxheU9yZGVyOw0KICAgIDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5wdWJsaWM8L3NwYW4+IFN5c3RlbS5EYXRlVHtbJiomXX1pbWUgQ3JlYXRlRGF0ZVV0YzsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+cHVibGljPC9zcGFuPiA8c3BhbiBjbGFzc3tbJiomXX09XFxcImhsLWtleXdvcmRcXFwiPmJvb2w8L3NwYW4+IElzRGVsZXRlZDsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+cHVibGl7WyYqJl19Yzwvc3Bhbj4gPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnN0cmluZzwvc3Bhbj4gRmlsdGVyOw0KICAgIDxzcGFuIGNsYXNzPVxce1smKiZdfVwiaGwta2V5d29yZFxcXCI+cHVibGljPC9zcGFuPiA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+c3RyaW5nPC9zcGFuPiBHcm91cEJ5e1smKiZdfTsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+cHVibGljPC9zcGFuPiA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+c3tbJiomXX10cmluZzwvc3Bhbj4gT3JkZXJCeTsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+cHVibGljPC9zcGFuPiA8c3BhbiBjbHtbJiomXX1hc3M9XFxcImhsLWtleXdvcmRcXFwiPmJvb2w8L3NwYW4+IElzT3V0ZXI7DQogICAgPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnB1Ymx7WyYqJl19aWM8L3NwYW4+IDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5zdHJpbmc8L3NwYW4+IEpvaW5UeXBlOw0KICAgIDxzcGFuIGNsYXN7WyYqJl19cz1cXFwiaGwta2V5d29yZFxcXCI+cHVibGljPC9zcGFuPiA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+c3RyaW5nPC9zcGFuPiBWYWx1e1smKiZdfWVUeXBlOw0KICAgIDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5wdWJsaWM8L3NwYW4+IFJlcG9ydFRhYmxlIFJlcG9ydFRhYmxle1smKiZdfTsNCn1cIjt7WyYqJl19[[/code]]

Having gathered together List<ReportDetail>, we pass it to the method, which will build us an SQL query:
[[code]]czo4NzczOlwic3RyaW5nIHNxbCA9IEJ1aWxkU3FsIChyZXBvcnREZXRhaWxzLlRvTGlzdCgpKTsNCnByaXZhdGUgc3RyaW5nIEJ1aWx7WyYqJl19ZFNxbCAoPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkxpc3Q8L3NwYW4+Jmx0O1JlcG9ydERldGFpbCZndDsgZGV0YWlscykNCnt7WyYqJl19DQogICAgPHNwYW4gY2xhc3M9XFxcImhsLWNvbW1lbnRcXFwiPi8qIGRlY2xhcmUgdmFyaWFibGVzDQpmb3Igd29ya2luZyB3aXRoIHN0cml7WyYqJl19bmdzIHdlIHVzZSBTdHJpbmdCdWlsZGVyLCBpbnN0ZWFkIG9mIFN0cmluZywgc2luY2Ugd2UgbmVlZCB0byByZXBlYXRlZGx5IG1vZHtbJiomXX1pZnkgdGhlIHN0cmluZy4gICAqLzwvc3Bhbj4gIA0KU3RyaW5nQnVpbGRlciBzcWwgPSBuZXcgU3RyaW5nQnVpbGRlcigpOw0KPHNwe1smKiZdfWFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj52YXI8L3NwYW4+IHRhYmxlcyA9IG5ldyA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+THtbJiomXX1pc3Q8L3NwYW4+Jmx0O3N0cmluZyZndDsoKTsNClN0cmluZ0J1aWxkZXIgc2VsZWN0ID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsNClN0e1smKiZdfXJpbmdCdWlsZGVyIGZyb20gPSBuZXcgU3RyaW5nQnVpbGRlcigpOw0KU3RyaW5nQnVpbGRlciB3aGVyZSA9IG5ldyBTdHJpbmdCdWl7WyYqJl19bGRlcigpOw0KU3RyaW5nQnVpbGRlciBkZWZhdWx0RmlsdGVycyA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7DQo8c3BhbiBjbGFzcz1cXFwie1smKiZdfWhsLWNvbW1lbnRcXFwiPi8vIGJ1aWxkIHNlbGVjdCBhbmQgZnJvbSBzZWN0aW9uczo8L3NwYW4+DQo8c3BhbiBjbGFzcz1cXFwiaGwta2V5e1smKiZdfXdvcmRcXFwiPmZvcmVhY2g8L3NwYW4+ICg8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+dmFyPC9zcGFuPiBkZXRhaWwgPHNwYW4gY2x7WyYqJl19YXNzPVxcXCJobC1rZXl3b3JkXFxcIj5pbjwvc3Bhbj4gZGV0YWlscykNCnsNCjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj52YXI8L3Nwe1smKiZdfWFuPiBmaWVsZCA9IGRldGFpbC5GaWVsZE5hbWU7DQo8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+dmFyPC9zcGFuPiA8c3BhbiBje1smKiZdfWxhc3M9XFxcImhsLWtleXdvcmRcXFwiPnRhYmxlPC9zcGFuPiA9IGRldGFpbC5UYWJsZU5hbWU7DQo8c3BhbiBjbGFzcz1cXFwiaGwta2V5d297WyYqJl19cmRcXFwiPnZhcjwvc3Bhbj4gZmlsdGVyID0gZGV0YWlsLkZpbHRlcjsNCjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj52YXI8L3NwYXtbJiomXX1uPiBqb2luVHlwZSA9IGRldGFpbC5Kb2luVHlwZTsNCjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj52YXI8L3NwYW4+IGlzTG9jYXtbJiomXX1sID0gY3J0LklzTG9jYWw7DQo8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+dmFyPC9zcGFuPiBkZWZhdWx0RmlsdGVyID0gY3J0LntbJiomXX1EZWZhdWx0RmlsdGVyOw0KPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj4gZmllbGQgPSBkZXRhaWwuRmllbGROYXtbJiomXX1tZTsNCjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj52YXI8L3NwYW4+IGZpbHRlciA9IGRldGFpbC5GaWx0ZXI7DQo8c3BhbiBjbHtbJiomXX1hc3M9XFxcImhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj4gcnQgPSBkZXRhaWwuUmVwb3J0VGFibGU7DQo8c3BhbiBjbGFzcz1cXFwiaGwta2V5e1smKiZdfXdvcmRcXFwiPnZhcjwvc3Bhbj4gam9pbk9uID0gcnQuSm9pbk9uOw0KPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj57WyYqJl19IGxvY2FsUHJlZml4ID0gPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIkBzZXJ2ZXJALmRiby5cXFwiPC9zcGFuPjsNCjxzcGFuIGNse1smKiZdfWFzcz1cXFwiaGwta2V5d29yZFxcXCI+dmFyPC9zcGFuPiBkZWZhdWx0Sm9pblR5cGUgPSBydC5EZWZhdWx0Sm9pblR5cGU7DQo8c3BhbiBje1smKiZdfWxhc3M9XFxcImhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj4gam9pblR5cGUgPSBqb2luVHlwZSA/PyBkZWZhdWx0Sm9pblR5cGU7DQo8c3Bhe1smKiZdfW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj4gZnJpZW5kbHlOYW1lID0gR2V0RnJpZW5kbHlOYW1lKDxzcGFuIGNsYXNze1smKiZdfT1cXFwiaGwta2V5d29yZFxcXCI+dGFibGU8L3NwYW4+LCBmaWVsZCk7DQo8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+aWY8L3NwYW4+IHtbJiomXX0oc2VsZWN0Lkxlbmd0aCA9PSAwKQ0Kew0KICAgIHNlbGVjdC48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPntbJiomXX0oPHNwYW4gY2xhc3M9XFxcImhsLWJ1aWx0X2luXFxcIj5zdHJpbmc8L3NwYW4+DQogICAgICAgICAgLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3e1smKiZdfW9yZFxcXCI+Rm9ybWF0PC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwic2VsZWN0IFt7MH1dLlt7MX1dIEFTIHsyfVxcXCI8e1smKiZdfS9zcGFuPiwgPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnRhYmxlPC9zcGFuPiwgZmllbGQsIGZyaWVuZGx5TmFtZSkpDQp9DQo8e1smKiZdfXNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPmVsc2U8L3NwYW4+DQp7DQogICAgc2VsZWN0LjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3J7WyYqJl19ZFxcXCI+QXBwZW5kPC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiLFtcXFwiPC9zcGFuPikuPHNwYW4gY2xhc3M9XFxcImhsLXtbJiomXX1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj50YWJsZTwvc3Bhbj4pLjxzcGFuIGNsYXNze1smKiZdfT1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiXS5bXFxcIjwvc3Bhbj4pDQogICB7WyYqJl19ICAgICAgIC48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPihmaWVsZCkuPHNwYW4gY2xhc3M9XFxcImhsLWtleXtbJiomXX13b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KDxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCJdIEFTIFxcXCI8L3NwYW4+KS48c3BhbiBjbGFzc3tbJiomXX09XFxcImhsLWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4oZnJpZW5kbHlOYW1lKTsNCn0NCjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj57WyYqJl19aWY8L3NwYW4+ICghdGFibGVzLkNvbnRhaW5zKDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj50YWJsZTwvc3Bhbj4pKQ0Kew0KPHN7WyYqJl19cGFuIGNsYXNzPVxcXCJobC1jb21tZW50XFxcIj4vLyBkZWZhdWx0IGZpbHRlcnM8L3NwYW4+DQogICAgICA8c3BhbiBjbGFzcz1cXFwiaGwta3tbJiomXX1leXdvcmRcXFwiPmlmPC9zcGFuPiAoIXN0cmluZy5Jc051bGxPckVtcHR5KGRlZmF1bHRGaWx0ZXIpKQ0KICAgICB7DQogICAgICAgICB7WyYqJl19PHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPmlmPC9zcGFuPiAoZGVmYXVsdEZpbHRlcnMuTGVuZ3RoID09IDApDQogICAgICAgICB7WyYqJl19ew0KICAgICAgICAgICAgIGRlZmF1bHRGaWx0ZXJzID0gZGVmYXVsdEZpbHRlcnMuPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkF7WyYqJl19cHBlbmQ8L3NwYW4+KChcXFwiKSAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIC48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxce1smKiZdfVwiPkFwcGVuZDwvc3Bhbj4oZGVmYXVsdEZpbHRlcikuPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4oPHNwYXtbJiomXX1uIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCIpXFxcIjwvc3Bhbj4pOw0KICAgICAgICAgfQ0KICAgICAgICAgPHNwYW4gY2xhc3M9XFxcImhsLXtbJiomXX1rZXl3b3JkXFxcIj5lbHNlPC9zcGFuPg0KICAgICAgICAgew0KICAgICAgICAgICAgIGRlZmF1bHRGaWx0ZXJzLjxzcGFuIGNsYXNzPVxce1smKiZdfVwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiIGFuZCAoXFxcIjwvc3Bhbj4pLjxzcHtbJiomXX1hbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPihkZWZhdWx0RmlsdGVyKS48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29ye1smKiZdfWRcXFwiPkFwcGVuZDwvc3Bhbj4oPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIilcXFwiPC9zcGFuPik7DQogICAgICAgICB9DQogICAge1smKiZdfSB9DQogICAgIDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5pZjwvc3Bhbj4gKGZyb20uTGVuZ3RoID09IDApDQogICAgIHsNCiAge1smKiZdfSAgICAgICAgICBmcm9tID0gZnJvbS48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+Q2xlYXI8L3NwYW4+KCkuPHNwYW4gY2xhc3M9e1smKiZdfVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KDxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCJmcm9tIFxcXCI8L3NwYW4+KS48c3B7WyYqJl19YW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4obG9jYWxQcmVmaXgpDQogICAgICAgICAgICAgICAgICAgICAgICB7WyYqJl19ICAgICAgLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KDxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCJ7WyYqJl19W1xcXCI8L3NwYW4+KSAuPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4oPHNwYW4gY2xhc3M9XFxcImhsLWtleXdve1smKiZdfXJkXFxcIj50YWJsZTwvc3Bhbj4pLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KDxzcGFuIGNsYXNzPVxcXCJobHtbJiomXX0tc3RyaW5nXFxcIj5cXFwiXVxcXCI8L3NwYW4+KTsNCiAgICAgfQ0KICAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+ZWxzZTwvc3BhbntbJiomXX0+DQogICAgIHsNCiAgICAgICAgICAgIGZyb20uPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4oPHNwYW4gY3tbJiomXX1sYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCIgXFxcIjwvc3Bhbj4pLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KGpve1smKiZdfWluVHlwZSkpIC48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIntbJiomXX0+XFxcIiBqb2luIFxcXCI8L3NwYW4+KSAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAuPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXHtbJiomXX1cIj5BcHBlbmQ8L3NwYW4+KGxvY2FsUHJlZml4KS48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPig8c3BhbiB7WyYqJl19Y2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIltcXFwiPC9zcGFuPikuPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4oPHtbJiomXX1zcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj50YWJsZTwvc3Bhbj4pDQogICAgICAgICAgICAgICAgLjxzcGFuIGNsYXNzPVxcXCJobC1re1smKiZdfWV5d29yZFxcXCI+QXBwZW5kPC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiXSBvbiBcXFwiPC9zcGFuPikuPHNwYW4gY2xhe1smKiZdfXNzPVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KGpvaW5Pbik7DQogICAgIH0NCn0NCiAgICAgPHNwYW4gY2xhc3M9XFxcImhsLWt7WyYqJl19ZXl3b3JkXFxcIj5pZjwvc3Bhbj4gKCF0YWJsZXMuQ29udGFpbnMoPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnRhYmxlPC9zcGFuPntbJiomXX0pKQ0KICAgICB7DQogICAgICAgICB0YWJsZXMuQWRkKDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj50YWJsZTwvc3Bhbj4pOw0KIHtbJiomXX0gICAgfQ0KfQ0KPHNwYW4gY2xhc3M9XFxcImhsLWNvbW1lbnRcXFwiPi8vYWRkIGZpbHRlcnMgdG8gdGhlIHdoZXJlIHNlY3Rpb248L3NwYXtbJiomXX1uPg0KaW50IGNsYXVzZUNvdW50ID0gZGV0YWlscy5XaGVyZSh4ID0mZ3Q7ICFzdHJpbmcuSXNOdWxsT3JFbXB0eSh4LkZpbHRlcikpe1smKiZdfS48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+Q291bnQ8L3NwYW4+KCk7DQppbnQgPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPntbJiomXX1vcmRlcjwvc3Bhbj4gPSAxOw0KPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPmZvcmVhY2g8L3NwYW4+ICg8c3BhbiBjbGFzcz1cXFwie1smKiZdfWhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj4gZGV0YWlsIDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5pbjwvc3Bhbj4gZGV0YWlscy57WyYqJl19V2hlcmUoeCA9Jmd0OyAhc3RyaW5nLklzTnVsbE9yRW1wdHkoeC5GaWx0ZXIpKS5Ub0xpc3QoKSkNCnsNCjxzcGFuIGNsYXNzPVxcXCJoe1smKiZdfWwta2V5d29yZFxcXCI+aWY8L3NwYW4+ICh3aGVyZS5MZW5ndGggPT0gMCkNCiAgICAgew0KICAgICAgICAgICAgd2hlcmUgPSB3aGVyZXtbJiomXX0uPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkNsZWFyPC9zcGFuPigpLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmR7WyYqJl19PC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiKFxcXCI8L3NwYW4+ICsgZGV0YWlsLkZpbHRlciArIDxzcGFuIGNsYXNze1smKiZdfT1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiKVxcXCI8L3NwYW4+KQ0KICAgICAgICAgICAgICAgICAgICAgICAgIC48c3BhbiBjbGFzcz1cXFwiaGwta2V5e1smKiZdfXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4oKGNsYXVzZUNvdW50ICE9IDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5vcmRlcjwvc3Bhbj57WyYqJl19ID8gPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIiBBTkRcXFwiPC9zcGFuPiA6IDxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCJcXHtbJiomXX1cIjwvc3Bhbj4pICsgPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIiBcXFwiPC9zcGFuPik7DQogICAgIH0NCiAgICAgPHNwYW4gY2xhe1smKiZdfXNzPVxcXCJobC1rZXl3b3JkXFxcIj5lbHNlPC9zcGFuPg0KICAgICB7DQogICAgICAgICB3aGVyZS48c3BhbiBjbGFzcz1cXFwiaGwta2V5d297WyYqJl19cmRcXFwiPkFwcGVuZDwvc3Bhbj4oPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIihcXFwiPC9zcGFuPiArIGRldGFpbC5GaWx0ZXIgKyB7WyYqJl19PHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIilcXFwiPC9zcGFuPikNCiAgICAgICAgIC48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxce1smKiZdfVwiPkFwcGVuZDwvc3Bhbj4oKGNsYXVzZUNvdW50ICE9IDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5vcmRlcjwvc3Bhbj4gPyA8c3tbJiomXX1wYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIiBBTkRcXFwiPC9zcGFuPiA6IDxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCJcXFwiPC9zcHtbJiomXX1hbj4pICsgPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIiBcXFwiPC9zcGFuPik7DQogICAgIH0NCiAgICAgPHNwYW4gY2xhc3M9XFxcIntbJiomXX1obC1rZXl3b3JkXFxcIj5vcmRlcjwvc3Bhbj4rKzsNCn0NCjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj52YXI8L3NwYW4+IHN1Yldoe1smKiZdfWVyZSA9IHdoZXJlLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5Ub1N0cmluZzwvc3Bhbj4oKTsNCndoZXJlLjxzcGFuIGNsYXNze1smKiZdfT1cXFwiaGwta2V5d29yZFxcXCI+Q2xlYXI8L3NwYW4+KCkuPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4oPHNwYXtbJiomXX1uIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCIgbndoZXJlIFxcXCI8L3NwYW4+KQ0KICAgICAgIC48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZHtbJiomXX1cXFwiPkFwcGVuZDwvc3Bhbj4oKHN1YldoZXJlLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5Ub1N0cmluZzwvc3Bhbj4oKSAhPSA8e1smKiZdfXNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIlxcXCI8L3NwYW4+ID8gc3ViV2hlcmUuPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPlR7WyYqJl19b1N0cmluZzwvc3Bhbj4oKSA6IDxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCJcXFwiPC9zcGFuPikpDQogICAgICAgLjxzcGFuIGNse1smKiZdfWFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPigoZGVmYXVsdEZpbHRlcnMNCiAgICAgICAuPHNwYW4gY2xhc3M9XFxcImhsLWt7WyYqJl19ZXl3b3JkXFxcIj5Ub1N0cmluZzwvc3Bhbj4oKSAhPSA8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiXFxcIjwvc3Bhbj4gPyAoc3ViV2h7WyYqJl19ZXJlLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5Ub1N0cmluZzwvc3Bhbj4oKSAhPSA8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFx7WyYqJl19XCI+XFxcIlxcXCI8L3NwYW4+ID8gPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIiBhbmQgXFxcIjwvc3Bhbj4gOiA8c3BhbiBjbGFzcz1cXFwiaHtbJiomXX1sLXN0cmluZ1xcXCI+XFxcIlxcXCI8L3NwYW4+KSArIGRlZmF1bHRGaWx0ZXJzLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5Ub1N0cmluZ3tbJiomXX08L3NwYW4+KCkgOiA8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiXFxcIjwvc3Bhbj4pKTsNCjxzcGFuIGNsYXNzPVxcXCJobC1jb21tZXtbJiomXX1udFxcXCI+Ly8gYXBwZW5kIHRoZSBxdWVyeSBzdHJpbmc8L3NwYW4+DQpzcWwgPSBzZWxlY3QuQ29weVRvKHNxbCkuPHNwYW4gY2xhc3N7WyYqJl19PVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KDxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCJuXFxcIjwvc3Bhbj4pLjxzcGFuIHtbJiomXX1jbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFuPihmcm9tKQ0KICAgICAgICAgICAgLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3e1smKiZdfW9yZFxcXCI+QXBwZW5kPC9zcGFuPig8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiblxcXCI8L3NwYW4+KS48c3BhbiBjbGFzcz1cXFwiaGx7WyYqJl19LWtleXdvcmRcXFwiPkFwcGVuZDwvc3Bhbj4od2hlcmUpLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5BcHBlbmQ8L3NwYW4+KDxzcHtbJiomXX1hbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiblxcXCI8L3NwYW4+KS48c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+QXBwZW5kPC9zcGFue1smKiZdfT4oPHNwYW4gY2xhc3M9XFxcImhsLXN0cmluZ1xcXCI+XFxcIm5cXFwiPC9zcGFuPik7DQo8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+cmV0dXJ7WyYqJl19bjwvc3Bhbj4gc3FsLjxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5Ub1N0cmluZzwvc3Bhbj4oKTsNCn0NCjxzcGFuIGNsYXNzPVxce1smKiZdfVwiaGwta2V5d29yZFxcXCI+QXM8L3NwYW4+IGEgcmVzdWx0LCB3ZSBnb3QgYSByZWFkeSBTUUwgPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcntbJiomXX1kXFxcIj5xdWVyeTwvc3Bhbj4gY29kZS4gSXQgcmVtYWlucyBvbmx5IHRvIDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5ydW48L3Nwe1smKiZdfWFuPiBpdCBhbmQgZ2V0IGEgZGF0YSA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+c2V0PC9zcGFuPjoNCnVzaW5nICg8c3BhbiBje1smKiZdfWxhc3M9XFxcImhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj4gY29ubmVjdGlvbiA9IG5ldyBTcWxDb25uZWN0aW9uKGNvbm5lY3Rpb25TdHJpe1smKiZdfW5nKSkNCnsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+dmFyPC9zcGFuPiBkYXRhU2V0ID0gbmV3IERhdGFTZXQoKTsNe1smKiZdfQogICAgPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnZhcjwvc3Bhbj4gZGF0YUFkYXB0ZXIgPSBuZXcgU3FsRGF0YUFkYXB0ZXIoe1smKiZdfXNxbCwgY29ubmVjdGlvbik7DQogICAgZGF0YUFkYXB0ZXIuRmlsbChkYXRhU2V0KTsNCiAgICA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d3tbJiomXX1vcmRcXFwiPnJldHVybjwvc3Bhbj4gZGF0YVNldC5UYWJsZXNbMF07DQp9XCI7e1smKiZdfQ==[[/code]]

Per page loading and unloading of the number of all entries.
To implement this part, we will use the previously created SQL code, simply by wrapping it in the additional code.
For example, let’s create a query string to obtain the number of all entries:
[[code]]czoxNjI6XCI8c3BhbiBjbGFzcz1cXFwiaGwtYXR0cmlidXRlXFxcIj52YXIgY291bnRRdWVyeTwvc3Bhbj4gPSA8c3BhbiBjbGFzcz1cXFwiaGx7WyYqJl19LXN0cmluZ1xcXCI+XFxcInNlbGVjdCBjb3VudCgxKSBmcm9tIChcXFwiPC9zcGFuPisgc3FsICs8c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj57WyYqJl19XFxcIikgc3ViXFxcIjwvc3Bhbj47XCI7e1smKiZdfQ==[[/code]]

Per page loading is implemented in much the same:
[[code]]czo5OTY6XCJzdHJpbmcgc3FsV2l0aG91dFBhZ2luZyA9IHN0cmluZw0KLkZvcm1hdChcXFwiPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXHtbJiomXX1cIj5zZWxlY3Q8L3NwYW4+IHRvcCB7PHNwYW4gY2xhc3M9XFxcImhsLW51bWJlclxcXCI+MDwvc3Bhbj59ICogPHNwYW4gY2xhc3M9XFxcImhsLXtbJiomXX1rZXl3b3JkXFxcIj5mcm9tPC9zcGFuPiAoPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnNlbGVjdDwvc3Bhbj4gcm93X251bWJlcigpe1smKiZdfSAgPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPm92ZXI8L3NwYW4+KDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5vcmRlcjwvc3tbJiomXX1wYW4+IDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5ieTwvc3Bhbj4gezxzcGFuIGNsYXNzPVxcXCJobC1udW1iZXJcXFwiPjE8L3NwYW57WyYqJl19Pn0pIDxzcGFuIGNsYXNzPVxcXCJobC1rZXl3b3JkXFxcIj5hczwvc3Bhbj4gPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPnJvd2lkPC9ze1smKiZdfXBhbj4sIHs8c3BhbiBjbGFzcz1cXFwiaGwtbnVtYmVyXFxcIj4yPC9zcGFuPn0pIHN1YjxzcGFuIGNsYXNzPVxcXCJobC1zdHJpbmdcXFwiPlxcXCIse1smKiZdfQ0KdGFrZSwNCkdldEZyaWVuZGx5TmFtZShkZXRhaWxzWzBdLlRhYmxlTmFtZSxkZXRhaWxzWzBdLkZpZWxkTmFtZSkNCixzcWwuU3V7WyYqJl19YnN0cmluZyg2KSk7DQpzcWwgPSBzdHJpbmcuRm9ybWF0KFxcXCI8L3NwYW4+ezxzcGFuIGNsYXNzPVxcXCJobC1udW1iZXJcXFwiPjA8L3NwYXtbJiomXX1uPn0gPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPndoZXJlPC9zcGFuPiA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+cm93aWR7WyYqJl19PC9zcGFuPiA8c3BhbiBjbGFzcz1cXFwiaGwta2V5d29yZFxcXCI+YmV0d2Vlbjwvc3Bhbj4gezxzcGFuIGNsYXNzPVxcXCJobC1udW1iZXJcXFwie1smKiZdfT4xPC9zcGFuPn0gPHNwYW4gY2xhc3M9XFxcImhsLWtleXdvcmRcXFwiPmFuZDwvc3Bhbj4gezxzcGFuIGNsYXNzPVxcXCJobC1udW1iZXJcXFwiPntbJiomXX0yPC9zcGFuPn08c3BhbiBjbGFzcz1cXFwiaGwtc3RyaW5nXFxcIj5cXFwiLCBzcWxXaXRob3V0UGFnaW5nLCAoc2tpcCArIDEpLCAoc2tpcCAre1smKiZdfSB0YWtlKSk7PC9zcGFuPlwiO3tbJiomXX0=[[/code]]