2 Copyright (c) 2013, Ford Motor Company
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 Redistributions of source code must retain the above copyright notice, this
9 list of conditions and the following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following
13 disclaimer in the documentation and/or other materials provided with the
16 Neither the name of the Ford Motor Company nor the names of its contributors
17 may be used to endorse or promote products derived from this software
18 without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
34 #include "utils/logger.h"
35 #include "policy/sql_pt_representation.h"
36 #include "policy/sql_wrapper.h"
37 #include "policy/sql_pt_queries.h"
39 # include "config_profile/profile.h"
44 CREATE_LOGGERPTR_GLOBAL(logger_, "SQLPTRepresentation")
47 template<typename T, typename K> void InsertUnique(K value, T* array) {
49 for (; i < array->size() && array->at(i) != value; ++i) {
52 if (array->size() == i) {
53 array->push_back(value);
59 const std::string SQLPTRepresentation::kDatabaseName = "policy";
61 SQLPTRepresentation::SQLPTRepresentation()
62 : db_(new dbms::SQLDatabase(kDatabaseName)) {
64 std::string path = profile::Profile::instance()->app_storage_folder();
66 db_->set_path(path + "/");
71 SQLPTRepresentation::~SQLPTRepresentation() {
76 CheckPermissionResult SQLPTRepresentation::CheckPermissions(
77 const PTString& app_id, const PTString& hmi_level, const PTString& rpc) {
78 CheckPermissionResult result;
79 dbms::SQLQuery query(db());
81 if (!query.Prepare(sql_pt::kSelectRpc)) {
84 "Incorrect select statement from rpcs" << query.LastError().text());
87 query.Bind(0, app_id);
88 query.Bind(1, hmi_level);
91 bool ret = query.Next();
92 result.hmi_level_permitted = ret ? kRpcAllowed : kRpcDisallowed;
96 << (result.hmi_level_permitted == kRpcAllowed ? "permitted" : "not permitted"));
97 std::string parameter;
99 if (!query.IsNull(0)) {
100 if (!result.list_of_allowed_params) {
101 result.list_of_allowed_params = new std::vector<PTString>();
103 parameter = query.GetString(0);
104 result.list_of_allowed_params->push_back(parameter);
112 bool SQLPTRepresentation::IsPTPreloaded() {
113 dbms::SQLQuery query(db());
114 return query.Prepare(sql_pt::kSelectPreloaded) && query.Next();
117 int SQLPTRepresentation::IgnitionCyclesBeforeExchange() {
118 dbms::SQLQuery query(db());
119 if (!query.Prepare(sql_pt::kSelectIgnitionCycles) || !query.Exec()) {
120 LOG4CXX_WARN(logger_, "Can not select ignition cycles");
123 int limit = query.GetInteger(0);
124 int current = query.GetInteger(1);
126 if (limit < 0 || current < 0 || current > limit) {
130 return limit - current;
133 int SQLPTRepresentation::KilometersBeforeExchange(int current) {
134 dbms::SQLQuery query(db());
135 if (!query.Prepare(sql_pt::kSelectKilometers) || !query.Exec()) {
136 LOG4CXX_WARN(logger_, "Can not select kilometers");
139 int limit = query.GetInteger(0);
140 int last = query.GetInteger(1);
142 if (limit < 0 || last < 0 || current < 0 || current < last
143 || limit < (current - last)) {
147 return limit - (current - last);
150 bool SQLPTRepresentation::SetCountersPassedForSuccessfulUpdate(
151 int kilometers, int days_after_epoch) {
152 LOG4CXX_INFO(logger_,
153 "SQLPTRepresentation::SetCountersPassedForSuccessfulUpdate");
154 dbms::SQLQuery query(db());
155 if (!query.Prepare(sql_pt::kUpdateCountersSuccessfulUpdate)) {
156 LOG4CXX_WARN(logger_,
157 "Wrong update query for counters on successful update.");
160 query.Bind(0, kilometers);
161 query.Bind(1, days_after_epoch);
163 LOG4CXX_WARN(logger_, "Failed to update counters on successful update.");
169 int SQLPTRepresentation::DaysBeforeExchange(int current) {
170 dbms::SQLQuery query(db());
171 if (!query.Prepare(sql_pt::kSelectDays) || !query.Exec()) {
172 LOG4CXX_WARN(logger_, "Can not select days");
175 int limit = query.GetInteger(0);
176 int last = query.GetInteger(1);
182 if (limit < 0 || last < 0 || current < 0 || current < last
183 || limit < (current - last)) {
187 return limit - (current - last);
190 int SQLPTRepresentation::TimeoutResponse() {
191 dbms::SQLQuery query(db());
192 if (!query.Prepare(sql_pt::kSelectTimeoutResponse) || !query.Exec()) {
193 LOG4CXX_INFO(logger_, "Can not select timeout response for retry sequence");
194 const int kDefault = 30;
197 return query.GetInteger(0);
200 bool SQLPTRepresentation::SecondsBetweenRetries(std::vector<int>* seconds) {
201 dbms::SQLQuery query(db());
202 if (!query.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
203 LOG4CXX_INFO(logger_,
204 "Incorrect select statement from seconds between retries");
207 while (query.Next()) {
208 seconds->push_back(query.GetInteger(0));
213 std::vector<UserFriendlyMessage> SQLPTRepresentation::GetUserFriendlyMsg(
214 const std::vector<std::string>& msg_codes, const std::string& language) {
215 std::vector<UserFriendlyMessage> result;
216 std::vector<std::string>::const_iterator it = msg_codes.begin();
217 std::vector<std::string>::const_iterator it_end = msg_codes.end();
218 for (; it != it_end; ++it) {
219 UserFriendlyMessage msg;
220 msg.message_code = *it;
221 result.push_back(msg);
226 EndpointUrls SQLPTRepresentation::GetUpdateUrls(int service_type) {
227 LOG4CXX_INFO(logger_, "SQLPTRepresentation::GetUpdateUrls for " << service_type);
228 dbms::SQLQuery query(db());
230 if (query.Prepare(sql_pt::kSelectEndpoint)) {
231 query.Bind(0, service_type);
232 while (query.Next()) {
235 data.url = query.GetString(0);
236 if (!query.IsNull(1)) {
237 data.app_id = query.GetString(1);
242 LOG4CXX_WARN(logger_, "Invalid select endpoints statement.");
247 int SQLPTRepresentation::GetNotificationsNumber(
248 policy_table::Priority priority) {
252 InitResult SQLPTRepresentation::Init() {
253 LOG4CXX_INFO(logger_, "SQLPTRepresentation::Init");
256 LOG4CXX_ERROR(logger_, "Failed opening database");
257 return InitResult::FAIL;
259 dbms::SQLQuery check_pages(db());
260 if (!check_pages.Prepare(sql_pt::kCheckPgNumber) || !check_pages.Next()) {
261 LOG4CXX_WARN(logger_, "Incorrect pragma for page counting.");
263 if (0 < check_pages.GetInteger(0)) {
264 dbms::SQLQuery db_check(db());
265 if (!db_check.Prepare(sql_pt::kCheckDBIntegrity)) {
266 LOG4CXX_WARN(logger_, "Incorrect pragma for integrity check.");
268 while (db_check.Next()) {
269 if (db_check.GetString(0).compare("ok") == 0) {
270 return InitResult::EXISTS;
272 LOG4CXX_ERROR(logger_,
273 "Existing policy table representation is invlaid.");
274 // TODO(PV): add handle
275 return InitResult::FAIL;
281 dbms::SQLQuery query(db());
282 if (!query.Exec(sql_pt::kCreateSchema)) {
285 "Failed creating schema of database: " << query.LastError().text());
286 return InitResult::FAIL;
288 if (!query.Exec(sql_pt::kInsertInitData)) {
291 "Failed insert init data to database: " << query.LastError().text());
292 return InitResult::FAIL;
294 return InitResult::SUCCESS;
297 bool SQLPTRepresentation::Close() {
299 return db_->LastError().number() == dbms::OK;
302 VehicleData SQLPTRepresentation::GetVehicleData() {
303 return VehicleData();
306 bool SQLPTRepresentation::Drop() {
307 dbms::SQLQuery query(db());
308 if (!query.Exec(sql_pt::kDropSchema)) {
309 LOG4CXX_WARN(logger_,
310 "Failed dropping database: " << query.LastError().text());
316 bool SQLPTRepresentation::Clear() {
317 dbms::SQLQuery query(db());
318 if (!query.Exec(sql_pt::kDeleteData)) {
319 LOG4CXX_ERROR(logger_,
320 "Failed clearing database: " << query.LastError().text());
323 if (!query.Exec(sql_pt::kInsertInitData)) {
326 "Failed insert init data to database: " << query.LastError().text());
332 utils::SharedPtr<policy_table::Table> SQLPTRepresentation::GenerateSnapshot() const {
333 LOG4CXX_INFO(logger_, "GenerateSnapshot");
334 utils::SharedPtr<policy_table::Table> table = new policy_table::Table();
335 GatherModuleMeta(&*table->policy_table.module_meta);
336 GatherModuleConfig(&table->policy_table.module_config);
337 GatherUsageAndErrorCounts(&*table->policy_table.usage_and_error_counts);
338 GatherDeviceData(&*table->policy_table.device_data);
339 GatherFunctionalGroupings(&table->policy_table.functional_groupings);
340 GatherConsumerFriendlyMessages(
341 &*table->policy_table.consumer_friendly_messages);
342 GatherApplicationPolicies(&table->policy_table.app_policies);
346 void SQLPTRepresentation::GatherModuleMeta(
347 policy_table::ModuleMeta* meta) const {
348 LOG4CXX_INFO(logger_, "Gather Module Meta Info");
349 meta->mark_initialized();
350 // Section Module Meta is empty for SDL specific
353 void SQLPTRepresentation::GatherModuleConfig(
354 policy_table::ModuleConfig* config) const {
355 LOG4CXX_INFO(logger_, "Gather Configuration Info");
356 dbms::SQLQuery query(db());
357 if (!query.Prepare(sql_pt::kSelectModuleConfig) || !query.Next()) {
358 LOG4CXX_WARN(logger_, "Incorrect select statement for module config");
360 *config->preloaded_pt = query.GetBoolean(0);
361 config->exchange_after_x_ignition_cycles = query.GetInteger(1);
362 config->exchange_after_x_kilometers = query.GetInteger(2);
363 config->exchange_after_x_days = query.GetInteger(3);
364 config->timeout_after_x_seconds = query.GetInteger(4);
365 *config->vehicle_make = query.GetString(5);
366 *config->vehicle_model = query.GetString(6);
367 *config->vehicle_year = query.GetString(7);
370 dbms::SQLQuery endpoints(db());
371 if (!endpoints.Prepare(sql_pt::kSelectEndpoints)) {
372 LOG4CXX_WARN(logger_, "Incorrect select statement for endpoints");
374 while (endpoints.Next()) {
375 std::stringstream stream;
376 stream << "0x0" << endpoints.GetInteger(1);
377 config->endpoints[stream.str()][endpoints.GetString(2)]
378 .push_back(endpoints.GetString(0));
382 dbms::SQLQuery notifications(db());
383 if (!notifications.Prepare(sql_pt::kSelectNotificationsPerMin)) {
384 LOG4CXX_WARN(logger_, "Incorrect select statement for notifications");
386 while (notifications.Next()) {
387 config->notifications_per_minute_by_priority[notifications.GetString(0)] =
388 notifications.GetInteger(1);
391 dbms::SQLQuery seconds(db());
392 if (!seconds.Prepare(sql_pt::kSelectSecondsBetweenRetries)) {
393 LOG4CXX_INFO(logger_,
394 "Incorrect select statement from seconds between retries");
396 while (seconds.Next()) {
397 config->seconds_between_retries.push_back(seconds.GetInteger(0));
402 bool SQLPTRepresentation::GatherUsageAndErrorCounts(
403 policy_table::UsageAndErrorCounts* counts) const {
404 LOG4CXX_INFO(logger_, "Gather Usage and Error Counts.");
405 dbms::SQLQuery query(db());
406 if (query.Prepare(sql_pt::kSelectAppLevels)) {
407 policy_table::AppLevel app_level_empty;
408 app_level_empty.mark_initialized();
409 while (query.Next()) {
410 (*counts->app_level)[query.GetString(0)] = app_level_empty;
416 void SQLPTRepresentation::GatherDeviceData(
417 policy_table::DeviceData* data) const {
418 LOG4CXX_INFO(logger_, "Gather device data.");
419 dbms::SQLQuery query(db());
420 if (query.Prepare(sql_pt::kSelectDeviceData)) {
421 policy_table::DeviceParams device_data_empty;
422 device_data_empty.mark_initialized();
423 while (query.Next()) {
424 (*data)[query.GetString(0)] = device_data_empty;
429 bool SQLPTRepresentation::GatherFunctionalGroupings(
430 policy_table::FunctionalGroupings* groups) const {
431 LOG4CXX_INFO(logger_, "Gather Functional Groupings info");
432 dbms::SQLQuery func_group(db());
433 if (!func_group.Prepare(sql_pt::kSelectFunctionalGroups)) {
434 LOG4CXX_WARN(logger_, "Incorrect select from functional_groupings");
437 dbms::SQLQuery rpcs(db());
438 if (!rpcs.Prepare(sql_pt::kSelectAllRpcs)) {
439 LOG4CXX_WARN(logger_, "Incorrect select all from rpc");
442 while (func_group.Next()) {
443 policy_table::Rpcs rpcs_tbl;
444 if (!func_group.IsNull(2)) {
445 *rpcs_tbl.user_consent_prompt = func_group.GetString(2);
447 int func_id = func_group.GetInteger(0);
448 rpcs.Bind(0, func_id);
449 while (rpcs.Next()) {
450 if (!rpcs.IsNull(1)) {
451 policy_table::HmiLevel level;
452 if (policy_table::EnumFromJsonString(rpcs.GetString(1), &level)) {
453 InsertUnique(level, &rpcs_tbl.rpcs[rpcs.GetString(0)].hmi_levels);
456 if (!rpcs.IsNull(2)) {
457 policy_table::Parameter param;
458 if (policy_table::EnumFromJsonString(rpcs.GetString(2), ¶m)) {
459 // TODO(IKozyrenko): Check logic if optional container is missing
460 InsertUnique(param, &(*rpcs_tbl.rpcs[rpcs.GetString(0)].parameters));
465 (*groups)[func_group.GetString(1)] = rpcs_tbl;
470 bool SQLPTRepresentation::GatherConsumerFriendlyMessages(
471 policy_table::ConsumerFriendlyMessages* messages) const {
472 LOG4CXX_INFO(logger_, "Gather Consumer Friendly Messages");
473 dbms::SQLQuery query(db());
474 if (!query.Prepare(sql_pt::kSelectUserMsgsVersion) || !query.Next()) {
475 LOG4CXX_WARN(logger_, "Incorrect select from consumer_friendly_messages");
478 messages->version = query.GetString(0);
482 bool SQLPTRepresentation::GatherApplicationPolicies(
483 policy_table::ApplicationPolicies* apps) const {
484 LOG4CXX_INFO(logger_, "Gather applications policies");
485 dbms::SQLQuery query(db());
486 if (!query.Prepare(sql_pt::kSelectAppPolicies)) {
487 LOG4CXX_WARN(logger_, "Incorrect select from app_policies");
491 while (query.Next()) {
492 rpc::Nullable<policy_table::ApplicationParams> params;
493 const std::string& app_id = query.GetString(0);
494 if (IsApplicationRevoked(app_id)) {
495 params.set_to_null();
496 (*apps)[app_id] = params;
499 *params.memory_kb = query.GetInteger(1);
500 *params.heart_beat_timeout_ms = query.GetInteger(2);
501 if (!query.IsNull(3)) {
502 *params.certificate = query.GetString(3);
504 if (!GatherAppGroup(app_id, ¶ms.groups)) {
507 // TODO(IKozyrenko): Check logic if optional container is missing
508 if (!GatherNickName(app_id, &*params.nicknames)) {
511 // TODO(IKozyrenko): Check logic if optional container is missing
512 if (!GatherAppType(app_id, &*params.AppHMIType)) {
515 (*apps)[app_id] = params;
520 bool SQLPTRepresentation::Save(const policy_table::Table& table) {
521 LOG4CXX_INFO(logger_, "SQLPTRepresentation::Save");
522 db_->BeginTransaction();
523 if (!SaveFunctionalGroupings(table.policy_table.functional_groupings)) {
524 db_->RollbackTransaction();
527 if (!SaveApplicationPolicies(table.policy_table.app_policies)) {
528 db_->RollbackTransaction();
531 if (!SaveModuleConfig(table.policy_table.module_config)) {
532 db_->RollbackTransaction();
535 if (!SaveConsumerFriendlyMessages(
536 *table.policy_table.consumer_friendly_messages)) {
537 db_->RollbackTransaction();
540 if (!SaveDeviceData(*table.policy_table.device_data)) {
541 db_->RollbackTransaction();
544 if (!SaveUsageAndErrorCounts(*table.policy_table.usage_and_error_counts)) {
545 db_->RollbackTransaction();
548 if (!SaveModuleMeta(*table.policy_table.module_meta)) {
549 db_->RollbackTransaction();
552 db_->CommitTransaction();
556 bool SQLPTRepresentation::SaveFunctionalGroupings(
557 const policy_table::FunctionalGroupings& groups) {
558 LOG4CXX_INFO(logger_, "SaveFunctionalGroupings");
559 dbms::SQLQuery query_delete(db());
560 if (!query_delete.Exec(sql_pt::kDeleteRpc)) {
561 LOG4CXX_WARN(logger_, "Incorrect delete from rpc.");
565 dbms::SQLQuery query(db());
566 if (!query.Exec(sql_pt::kDeleteFunctionalGroup)) {
567 LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
570 if (!query.Prepare(sql_pt::kInsertFunctionalGroup)) {
571 LOG4CXX_WARN(logger_, "Incorrect insert statement for functional groups");
575 policy_table::FunctionalGroupings::const_iterator it;
576 for (it = groups.begin(); it != groups.end(); ++it) {
577 query.Bind(0, it->first);
578 it->second.user_consent_prompt.is_initialized() ?
579 query.Bind(1, *(it->second.user_consent_prompt)) : query.Bind(1);
581 if (!query.Exec() || !query.Reset()) {
582 LOG4CXX_WARN(logger_, "Incorrect insert into functional groups");
586 if (!SaveRpcs(query.LastInsertId(), it->second.rpcs)) {
593 bool SQLPTRepresentation::SaveRpcs(int64_t group_id,
594 const policy_table::Rpc& rpcs) {
595 dbms::SQLQuery query(db());
596 dbms::SQLQuery query_parameter(db());
597 if (!query.Prepare(sql_pt::kInsertRpc)
598 || !query_parameter.Prepare(sql_pt::kInsertRpcWithParameter)) {
599 LOG4CXX_WARN(logger_, "Incorrect insert statement for rpc");
603 policy_table::Rpc::const_iterator it;
604 for (it = rpcs.begin(); it != rpcs.end(); ++it) {
605 const policy_table::HmiLevels& hmi_levels = it->second.hmi_levels;
606 // TODO(IKozyrenko): Check logic if optional container is missing
607 const policy_table::Parameters& parameters = *it->second.parameters;
608 policy_table::HmiLevels::const_iterator hmi_it;
609 policy_table::Parameters::const_iterator ps_it;
610 for (hmi_it = hmi_levels.begin(); hmi_it != hmi_levels.end(); ++hmi_it) {
611 if (!parameters.empty()) {
612 for (ps_it = parameters.begin(); ps_it != parameters.end(); ++ps_it) {
613 query_parameter.Bind(0, it->first);
614 query_parameter.Bind(
615 1, std::string(policy_table::EnumToJsonString(*hmi_it)));
616 query_parameter.Bind(
617 2, std::string(policy_table::EnumToJsonString(*ps_it)));
618 query_parameter.Bind(3, group_id);
619 if (!query_parameter.Exec() || !query_parameter.Reset()) {
620 LOG4CXX_WARN(logger_, "Incorrect insert into rpc with parameter");
625 query.Bind(0, it->first);
626 query.Bind(1, std::string(policy_table::EnumToJsonString(*hmi_it)));
627 query.Bind(2, group_id);
628 if (!query.Exec() || !query.Reset()) {
629 LOG4CXX_WARN(logger_, "Incorrect insert into rpc");
639 bool SQLPTRepresentation::SaveApplicationPolicies(
640 const policy_table::ApplicationPolicies& apps) {
641 LOG4CXX_INFO(logger_, "SaveApplicationPolicies");
642 dbms::SQLQuery query_delete(db());
643 if (!query_delete.Exec(sql_pt::kDeleteAppGroup)) {
644 LOG4CXX_WARN(logger_, "Incorrect delete from app_group.");
647 if (!query_delete.Exec(sql_pt::kDeleteApplication)) {
648 LOG4CXX_WARN(logger_, "Incorrect delete from application.");
651 policy_table::ApplicationPolicies::const_iterator it;
652 dbms::SQLQuery app_query(db());
653 if (!app_query.Prepare(sql_pt::kInsertApplication)) {
654 LOG4CXX_WARN(logger_, "Incorrect insert statement into application.");
657 for (it = apps.begin(); it != apps.end(); ++it) {
658 app_query.Bind(0, it->first);
659 app_query.Bind(1, it->second.is_null());
660 app_query.Bind(2, it->second.memory_kb);
661 app_query.Bind(3, it->second.heart_beat_timeout_ms);
662 it->second.certificate.is_initialized() ?
663 app_query.Bind(4, *it->second.certificate) : app_query.Bind(4);
665 if (!app_query.Exec() || !app_query.Reset()) {
666 LOG4CXX_WARN(logger_, "Incorrect insert into application.");
670 LOG4CXX_INFO(logger_, "Saving data for application: " << it->first);
671 if (it->second.is_string()) {
672 if (kDefaultId.compare(it->second.get_string()) == 0) {
673 if (!SetDefaultPolicy(it->first)) {
680 if (!SaveAppGroup(it->first, it->second.groups)) {
683 // TODO(IKozyrenko): Check logic if optional container is missing
684 if (!SaveNickname(it->first, *it->second.nicknames)) {
687 // TODO(IKozyrenko): Check logic if optional container is missing
688 if (!SaveAppType(it->first, *it->second.AppHMIType)) {
696 bool SQLPTRepresentation::SaveAppGroup(
697 const std::string& app_id, const policy_table::Strings& app_groups) {
698 dbms::SQLQuery query(db());
699 if (!query.Prepare(sql_pt::kInsertAppGroup)) {
700 LOG4CXX_WARN(logger_, "Incorrect insert statement for app group");
703 LOG4CXX_INFO(logger_, "SaveAppGroup");
704 policy_table::Strings::const_iterator it;
705 for (it = app_groups.begin(); it != app_groups.end(); ++it) {
706 std::string ssss = *it;
707 LOG4CXX_INFO(logger_, "Group: " << ssss);
708 query.Bind(0, app_id);
710 if (!query.Exec() || !query.Reset()) {
713 "Incorrect insert into app group." << query.LastError().text());
721 bool SQLPTRepresentation::SaveNickname(const std::string& app_id,
722 const policy_table::Strings& nicknames) {
723 dbms::SQLQuery query(db());
724 if (!query.Prepare(sql_pt::kInsertNickname)) {
725 LOG4CXX_WARN(logger_, "Incorrect insert statement for nickname");
729 policy_table::Strings::const_iterator it;
730 for (it = nicknames.begin(); it != nicknames.end(); ++it) {
731 query.Bind(0, app_id);
733 if (!query.Exec() || !query.Reset()) {
734 LOG4CXX_WARN(logger_, "Incorrect insert into nickname.");
742 bool SQLPTRepresentation::SaveAppType(const std::string& app_id,
743 const policy_table::AppHMITypes& types) {
744 dbms::SQLQuery query(db());
745 if (!query.Prepare(sql_pt::kInsertAppType)) {
746 LOG4CXX_WARN(logger_, "Incorrect insert statement for app type");
750 policy_table::AppHMITypes::const_iterator it;
751 for (it = types.begin(); it != types.end(); ++it) {
752 query.Bind(0, app_id);
753 query.Bind(1, std::string(policy_table::EnumToJsonString(*it)));
754 if (!query.Exec() || !query.Reset()) {
755 LOG4CXX_WARN(logger_, "Incorrect insert into app type.");
763 bool SQLPTRepresentation::SaveModuleMeta(const policy_table::ModuleMeta& meta) {
764 LOG4CXX_INFO(logger_, "SaveModuleMeta");
765 // Section Module Meta is empty for SDL specific
769 bool SQLPTRepresentation::SaveModuleConfig(
770 const policy_table::ModuleConfig& config) {
771 LOG4CXX_INFO(logger_, "SaveModuleConfig");
772 dbms::SQLQuery query(db());
773 if (!query.Prepare(sql_pt::kUpdateModuleConfig)) {
774 LOG4CXX_WARN(logger_, "Incorrect update statement for module config");
778 config.preloaded_pt.is_initialized() ?
779 query.Bind(0, config.preloaded_pt) : query.Bind(0, false);
780 query.Bind(1, config.exchange_after_x_ignition_cycles);
781 query.Bind(2, config.exchange_after_x_kilometers);
782 query.Bind(3, config.exchange_after_x_days);
783 query.Bind(4, config.timeout_after_x_seconds);
784 config.vehicle_make.is_initialized() ?
785 query.Bind(5, *(config.vehicle_make)) : query.Bind(5);
786 config.vehicle_model.is_initialized() ?
787 query.Bind(6, *(config.vehicle_model)) : query.Bind(6);
788 config.vehicle_year.is_initialized() ?
789 query.Bind(7, *(config.vehicle_year)) : query.Bind(7);
792 LOG4CXX_WARN(logger_, "Incorrect update module config");
796 if (!SaveSecondsBetweenRetries(config.seconds_between_retries)) {
800 if (!SaveNumberOfNotificationsPerMinute(
801 config.notifications_per_minute_by_priority)) {
805 if (!SaveServiceEndpoints(config.endpoints)) {
812 bool SQLPTRepresentation::SaveServiceEndpoints(
813 const policy_table::ServiceEndpoints& endpoints) {
814 dbms::SQLQuery query(db());
815 if (!query.Exec(sql_pt::kDeleteEndpoint)) {
816 LOG4CXX_WARN(logger_, "Incorrect delete from endpoint.");
820 if (!query.Prepare(sql_pt::kInsertEndpoint)) {
821 LOG4CXX_WARN(logger_, "Incorrect insert statement for endpoint");
825 policy_table::ServiceEndpoints::const_iterator it;
826 for (it = endpoints.begin(); it != endpoints.end(); ++it) {
827 const policy_table::URLList& apps = it->second;
828 policy_table::URLList::const_iterator app_it;
829 for (app_it = apps.begin(); app_it != apps.end(); ++app_it) {
830 const policy_table::URL& urls = app_it->second;
831 policy_table::URL::const_iterator url_it;
832 for (url_it = urls.begin(); url_it != urls.end(); ++url_it) {
833 std::stringstream temp_stream(it->first);
835 temp_stream.seekg(3);
836 temp_stream >> service;
837 query.Bind(0, service);
838 query.Bind(1, *url_it);
839 query.Bind(2, app_it->first);
841 LOG4CXX_WARN(logger_, "Incorrect insert into endpoint");
851 bool SQLPTRepresentation::SaveConsumerFriendlyMessages(
852 const policy_table::ConsumerFriendlyMessages& messages) {
853 LOG4CXX_INFO(logger_, "SaveConsumerFriendlyMessages");
855 dbms::SQLQuery query(db());
856 if (!query.Exec(sql_pt::kDeleteMessageString)) {
857 LOG4CXX_WARN(logger_, "Incorrect delete from message.");
861 if (query.Prepare(sql_pt::kUpdateVersion)) {
862 query.Bind(0, messages.version);
864 LOG4CXX_WARN(logger_, "Incorrect update into version.");
868 LOG4CXX_WARN(logger_, "Incorrect update statement for version.");
872 policy_table::Messages::const_iterator it;
873 // TODO(IKozyrenko): Check logic if optional container is missing
874 for (it = messages.messages->begin(); it != messages.messages->end(); ++it) {
875 if (!SaveMessageType(it->first)) {
878 const policy_table::Languages& langs = it->second.languages;
879 policy_table::Languages::const_iterator lang_it;
880 for (lang_it = langs.begin(); lang_it != langs.end(); ++lang_it) {
881 if (!SaveLanguage(lang_it->first)) {
884 if (!SaveMessageString(it->first, lang_it->first, lang_it->second)) {
893 bool SQLPTRepresentation::SaveMessageType(const std::string& type) {
894 dbms::SQLQuery query(db());
895 if (!query.Prepare(sql_pt::kInsertMessageType)) {
896 LOG4CXX_WARN(logger_, "Incorrect insert statement for message type.");
902 LOG4CXX_WARN(logger_, "Incorrect insert into message type.");
909 bool SQLPTRepresentation::SaveLanguage(const std::string& code) {
910 dbms::SQLQuery query(db());
911 if (!query.Prepare(sql_pt::kInsertLanguage)) {
912 LOG4CXX_WARN(logger_, "Incorrect insert statement for language.");
918 LOG4CXX_WARN(logger_, "Incorrect insert into language.");
925 bool SQLPTRepresentation::SaveMessageString(
926 const std::string& type, const std::string& lang,
927 const policy_table::MessageString& strings) {
928 // Section is empty for SDL specific
932 bool SQLPTRepresentation::SaveSecondsBetweenRetries(
933 const policy_table::SecondsBetweenRetries& seconds) {
934 dbms::SQLQuery query(db());
935 if (!query.Exec(sql_pt::kDeleteSecondsBetweenRetries)) {
936 LOG4CXX_WARN(logger_, "Incorrect delete from seconds between retries.");
939 if (!query.Prepare(sql_pt::kInsertSecondsBetweenRetry)) {
940 LOG4CXX_WARN(logger_,
941 "Incorrect insert statement for seconds between retries.");
945 for (int i = 0; i < seconds.size(); ++i) {
947 query.Bind(1, seconds[i]);
948 if (!query.Exec() || !query.Reset()) {
949 LOG4CXX_WARN(logger_, "Incorrect insert into seconds between retries.");
957 bool SQLPTRepresentation::SaveNumberOfNotificationsPerMinute(
958 const policy_table::NumberOfNotificationsPerMinute& notifications) {
959 dbms::SQLQuery query(db());
960 if (!query.Prepare(sql_pt::kInsertNotificationsByPriority)) {
961 LOG4CXX_WARN(logger_,
962 "Incorrect insert statement for notifications by priority.");
966 policy_table::NumberOfNotificationsPerMinute::const_iterator it;
967 for (it = notifications.begin(); it != notifications.end(); ++it) {
968 query.Bind(0, it->first);
969 query.Bind(1, it->second);
970 if (!query.Exec() || !query.Reset()) {
971 LOG4CXX_WARN(logger_, "Incorrect insert into notifications by priority.");
979 bool SQLPTRepresentation::SaveDeviceData(
980 const policy_table::DeviceData& devices) {
981 LOG4CXX_INFO(logger_, "SaveDeviceData");
982 dbms::SQLQuery query(db());
983 if (!query.Prepare(sql_pt::kInsertDeviceData)) {
984 LOG4CXX_WARN(logger_, "Incorrect insert statement for device data.");
988 policy_table::DeviceData::const_iterator it;
989 for (it = devices.begin(); it != devices.end(); ++it) {
990 query.Bind(0, it->first);
992 LOG4CXX_WARN(logger_, "Incorrect insert into device data.");
1000 bool SQLPTRepresentation::SaveUsageAndErrorCounts(
1001 const policy_table::UsageAndErrorCounts& counts) {
1002 LOG4CXX_INFO(logger_, "SaveUsageAndErrorCounts");
1003 dbms::SQLQuery query(db());
1004 if (!query.Exec(sql_pt::kDeleteAppLevel)) {
1005 LOG4CXX_WARN(logger_, "Incorrect delete from app level.");
1008 if (!query.Prepare(sql_pt::kInsertAppLevel)) {
1009 LOG4CXX_WARN(logger_, "Incorrect insert statement for app level.");
1013 policy_table::AppLevels::const_iterator it;
1014 const policy_table::AppLevels& app_levels = *counts.app_level;
1015 for (it = app_levels.begin(); it != app_levels.end(); ++it) {
1016 query.Bind(0, it->first);
1017 if (!query.Exec()) {
1018 LOG4CXX_WARN(logger_, "Incorrect insert into app level.");
1026 void SQLPTRepresentation::IncrementIgnitionCycles() {
1027 dbms::SQLQuery query(db());
1028 if (!query.Exec(sql_pt::kIncrementIgnitionCycles)) {
1029 LOG4CXX_WARN(logger_, "Failed incrementing ignition cycles");
1033 void SQLPTRepresentation::ResetIgnitionCycles() {
1034 LOG4CXX_INFO(logger_, "ResetIgnitionCycles");
1035 dbms::SQLQuery query(db());
1036 if (!query.Exec(sql_pt::kResetIgnitionCycles)) {
1037 LOG4CXX_WARN(logger_, "Failed to reset ignition cycles number.");
1041 bool SQLPTRepresentation::UpdateRequired() const {
1042 dbms::SQLQuery query(db());
1043 if (!query.Prepare(sql_pt::kSelectFlagUpdateRequired) || !query.Exec()) {
1044 LOG4CXX_WARN(logger_,
1045 "Failed select update required flag from module meta");
1048 return query.GetBoolean(0);
1051 void SQLPTRepresentation::SaveUpdateRequired(bool value) {
1052 dbms::SQLQuery query(db());
1053 if (!query.Prepare(sql_pt::kUpdateFlagUpdateRequired)) {
1054 LOG4CXX_WARN(logger_,
1055 "Incorrect update into module meta (update_required)");
1058 query.Bind(0, value);
1059 if (!query.Exec()) {
1060 LOG4CXX_WARN(logger_, "Failed update module meta (update_required)");
1064 bool SQLPTRepresentation::GetInitialAppData(const std::string& app_id,
1065 StringArray* nicknames,
1066 StringArray* app_types) {
1067 LOG4CXX_INFO(logger_, "Getting initial application data.");
1068 dbms::SQLQuery app_names(db());
1069 if (!app_names.Prepare(sql_pt::kSelectNicknames)) {
1070 LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
1073 dbms::SQLQuery app_hmi_types(db());
1074 if (!app_hmi_types.Prepare(sql_pt::kSelectAppTypes)) {
1075 LOG4CXX_WARN(logger_, "Incorrect select from app types");
1078 app_names.Bind(0, app_id);
1079 while (app_names.Next()) {
1080 nicknames->push_back(app_names.GetString(0));
1083 app_hmi_types.Bind(0, app_id);
1084 while (app_hmi_types.Next()) {
1085 app_types->push_back(app_names.GetString(0));
1087 app_hmi_types.Reset();
1091 bool SQLPTRepresentation::GetFunctionalGroupings(
1092 policy_table::FunctionalGroupings& groups) {
1093 LOG4CXX_INFO(logger_, "GetFunctionalGroupings");
1094 return GatherFunctionalGroupings(&groups);
1097 bool SQLPTRepresentation::GatherAppType(
1098 const std::string& app_id, policy_table::AppHMITypes* app_types) const {
1099 dbms::SQLQuery query(db());
1100 if (!query.Prepare(sql_pt::kSelectAppTypes)) {
1101 LOG4CXX_WARN(logger_, "Incorrect select from app types");
1105 query.Bind(0, app_id);
1106 while (query.Next()) {
1107 policy_table::AppHMIType type;
1108 if (!policy_table::EnumFromJsonString(query.GetString(0), &type)) {
1111 app_types->push_back(type);
1116 bool SQLPTRepresentation::GatherNickName(
1117 const std::string& app_id, policy_table::Strings* nicknames) const {
1118 dbms::SQLQuery query(db());
1119 if (!query.Prepare(sql_pt::kSelectNicknames)) {
1120 LOG4CXX_WARN(logger_, "Incorrect select from app nicknames");
1124 query.Bind(0, app_id);
1125 while (query.Next()) {
1126 nicknames->push_back(query.GetString(0));
1131 bool SQLPTRepresentation::GatherAppGroup(
1132 const std::string& app_id, policy_table::Strings* app_groups) const {
1133 dbms::SQLQuery query(db());
1134 if (!query.Prepare(sql_pt::kSelectAppGroups)) {
1135 LOG4CXX_WARN(logger_, "Incorrect select from app groups");
1139 query.Bind(0, app_id);
1140 while (query.Next()) {
1141 app_groups->push_back(query.GetString(0));
1146 bool SQLPTRepresentation::IsApplicationRevoked(
1147 const std::string& app_id) const {
1148 dbms::SQLQuery query(db());
1149 if (!query.Prepare(sql_pt::kSelectApplicationRevoked)) {
1150 LOG4CXX_WARN(logger_, "Incorrect select from is_revoked of application");
1154 query.Bind(0, app_id);
1155 if (!query.Exec()) {
1156 LOG4CXX_WARN(logger_, "Failed select is_revoked of application");
1159 return query.IsNull(0) ? false : query.GetBoolean(0);
1162 bool SQLPTRepresentation::IsApplicationRepresented(
1163 const std::string& app_id) const {
1164 dbms::SQLQuery query(db());
1165 if (!query.Prepare(sql_pt::kSelectApplicationRepresented)) {
1166 LOG4CXX_WARN(logger_, "Incorrect select application by id");
1170 query.Bind(0, app_id);
1171 if (!query.Exec()) {
1172 LOG4CXX_WARN(logger_, "Failed select application by id");
1175 return query.GetInteger(0) != 0;
1178 bool SQLPTRepresentation::IsDefaultPolicy(const std::string& app_id) const {
1179 dbms::SQLQuery query(db());
1180 if (!query.Prepare(sql_pt::kSelectApplicationIsDefault)) {
1181 LOG4CXX_WARN(logger_, "Incorrect select application by id");
1185 query.Bind(0, app_id);
1186 if (!query.Exec()) {
1187 LOG4CXX_WARN(logger_, "Failed select application by id");
1190 return query.IsNull(0) ? false : query.GetBoolean(0);
1193 bool SQLPTRepresentation::IsPredataPolicy(const std::string& app_id) const {
1197 bool SQLPTRepresentation::SetDefaultPolicy(const std::string& app_id) {
1198 policy_table::ApplicationPolicies apps;
1199 if (!GatherApplicationPolicies(&apps)) {
1200 LOG4CXX_WARN(logger_, "Failed gathering application policies");
1203 apps[app_id] = apps[kDefaultId];
1204 if (!SaveApplicationPolicies(apps)) {
1205 LOG4CXX_WARN(logger_, "Failed saving application policies");
1209 return SetIsDefault(app_id, true);
1212 bool SQLPTRepresentation::SetIsDefault(const std::string& app_id,
1213 bool is_default) const {
1214 LOG4CXX_TRACE(logger_, "Set flag is_default of application");
1215 dbms::SQLQuery query(db());
1216 if (!query.Prepare(sql_pt::kUpdateIsDefault)) {
1217 LOG4CXX_WARN(logger_, "Incorect statement for updating is_default");
1221 query.Bind(0, is_default);
1222 query.Bind(1, app_id);
1223 if (!query.Exec()) {
1224 LOG4CXX_WARN(logger_, "Failed update is_default");
1230 dbms::SQLDatabase* SQLPTRepresentation::db() const {
1232 dbms::SQLDatabase* db = new dbms::SQLDatabase(kDatabaseName);
1240 } // namespace policy