Navigation Menu

Skip to content

Commit

Permalink
[WIP] Dev: Issue with MSSQL and 0 or 0.1 or 0.001 (#1354)
Browse files Browse the repository at this point in the history
Fixed issue #15684: MSSQL issue reloading decimal value
Fixed issue #15685: Issue when exporting decimal value in MSSQL
  • Loading branch information
Shnoulle authored and olleharstedt committed Jan 8, 2020
1 parent 4ac5327 commit 2eb78e6
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 7 deletions.
6 changes: 6 additions & 0 deletions application/controllers/admin/dataentry.php
Expand Up @@ -598,6 +598,9 @@ public function editdata($subaction, $id, $surveyid)
$aDataentryoutput .= $fname['subquestion'].' ';
/* Fix DB DECIMAL type */
$value = $idrow[$fname['fieldname']];
if($value[0] === ".") {
$value = "0".$value;
}
if (strpos($value, ".")) {
$value = rtrim(rtrim($value, "0"), ".");
}
Expand Down Expand Up @@ -974,6 +977,9 @@ public function editdata($subaction, $id, $surveyid)
case "N": //NUMERICAL TEXT
/* Fix DB DECIMAL type */
$value = $idrow[$fname['fieldname']];
if($value[0] === ".") {
$value = "0".$value;
}
if (strpos($value, ".")) {
$value = rtrim(rtrim($value, "0"), ".");
}
Expand Down
5 changes: 4 additions & 1 deletion application/helpers/admin/export/SurveyObj.php
Expand Up @@ -100,7 +100,10 @@ public function getFullAnswer($fieldName, $answerCode, Translator $translator, $
case 'K':
case 'N':
$fullAnswer = $answerCode;
if (trim($fullAnswer) != '') {
if (trim($fullAnswer) !== '') {
if($fullAnswer[0] === ".") {
$fullAnswer = "0".$fullAnswer;
}
if (strpos($fullAnswer, ".") !== false) {
$fullAnswer = rtrim(rtrim($fullAnswer, "0"), ".");
}
Expand Down
7 changes: 6 additions & 1 deletion application/helpers/common_helper.php
Expand Up @@ -1096,7 +1096,7 @@ function getExtendedAnswer($iSurveyID, $sFieldCode, $sValue, $sLanguage)
//Fieldcode used to determine question, $sValue used to match against answer code
//Returns NULL if question type does not suit
if (strpos($sFieldCode, "{$iSurveyID}X") === 0) {
//Only check if it looks like a real fieldcode
//Only check if it looks like a real fieldcode
$fieldmap = createFieldMap($survey, 'short', false, false, $sLanguage);
if (isset($fieldmap[$sFieldCode])) {
$fields = $fieldmap[$sFieldCode];
Expand All @@ -1121,7 +1121,12 @@ function getExtendedAnswer($iSurveyID, $sFieldCode, $sValue, $sLanguage)
break;
case 'K':
case 'N':
// Fix the value : Value is stored as decimal in SQL
if (trim($sValue) != '') {
// issue #15685 mssql SAVE 0.01 AS .0100000000, set it at 0.0100000000
if($sValue[0] === ".") {
$sValue = "0".$sValue;
}
if (strpos($sValue, ".") !== false) {
$sValue = rtrim(rtrim($sValue, "0"), ".");
}
Expand Down
22 changes: 19 additions & 3 deletions application/helpers/expressions/em_core_helper.php
Expand Up @@ -298,9 +298,25 @@ private function getMismatchInformation(array $arg1, array $arg2)
{
/* When value come from DB : it's set to 1.000000 (DECIMAL) : must be fixed see #11163. Response::model() must fix this . or not ? */
/* Don't return true always : user can entre non numeric value in a numeric value : we must compare as string then */
$arg1[0] = ($arg1[2] == "NUMBER" && strpos($arg1[0], ".")) ? rtrim(rtrim($arg1[0], "0"), ".") : $arg1[0];
$arg2[0] = ($arg2[2] == "NUMBER" && strpos($arg2[0], ".")) ? rtrim(rtrim($arg2[0], "0"), ".") : $arg2[0];

$arg1[0] = $arg1[0];
if($arg1[2] == "NUMBER" && $arg1[0]!== "") {
if($arg1[0] === ".") {
$arg1 = "0".$arg1;
}
if (strpos($arg1, ".") !== false) {
$arg1 = rtrim(rtrim($arg1, "0"), ".");
}
}
$arg2[0] = $arg2[0];
if($arg2[2] == "NUMBER" && $arg2[0]!== "") {
if($arg2[0] === ".") {
$arg2 = "0".$arg2;
}
if (strpos($arg2, ".") !== false) {
$arg2 = rtrim(rtrim($arg2, "0"), ".");
}
}

$bNumericArg1 = $arg1[0]!== "" && (!$arg1[0] || strval(floatval($arg1[0])) == strval($arg1[0]));
$bNumericArg2 = $arg2[0]!== "" && (!$arg2[0] || strval(floatval($arg2[0])) == strval($arg2[0]));
$bStringArg1 = !$arg1[0] || !$bNumericArg1;
Expand Down
12 changes: 10 additions & 2 deletions application/helpers/qanda_helper.php
Expand Up @@ -2739,8 +2739,12 @@ function do_multiplenumeric($ia)
$sValue = null;
}

// Fix the display value : Value is stored as decimal in SQL
if($sValue[0] == ".") {
// issue #15684 mssql SAVE 0.01 AS .0100000000, set it at 0.0100000000
$sValue = "0" . $sValue;
}
$sUnformatedValue = $sValue ? $sValue : '';

if (strpos($sValue, ".")) {
$sValue = rtrim(rtrim($sValue, "0"), ".");
$sValue = str_replace('.', $sSeparator, $sValue);
Expand Down Expand Up @@ -2928,7 +2932,11 @@ function do_numerical($ia)
$sSeparator = getRadixPointData($thissurvey['surveyls_numberformat']);
$sSeparator = $sSeparator['separator'];

// Fix the display value : Value is stored as decimal in SQL then return dot and 0 after dot. Seems only for numerical question type
// Fix the display value : Value is stored as decimal in SQL
if($fValue[0] == ".") {
// issue #15684 mssql SAVE 0.01 AS .0100000000, set it at 0.0100000000
$fValue = "0" . $fValue;
}
if (strpos($fValue, ".")) {
$fValue = rtrim(rtrim($fValue, "0"), ".");
}
Expand Down
3 changes: 3 additions & 0 deletions application/models/SurveyDynamic.php
Expand Up @@ -959,6 +959,9 @@ public function getQuestionArray($oQuestion, $oResponses, $bHonorConditions, $su
}

if ($oQuestion->type=='N' || ($oQuestion->parent_qid != 0 && $oQuestion->parents['type'] === "K")) {
if($aQuestionAttributes['answervalue'] !=="" && $aQuestionAttributes['answervalue'][0] === ".") { // issue #15685 mssql
$aQuestionAttributes['answervalue'] = "0".$aQuestionAttributes['answervalue'];
}
if (strpos($aQuestionAttributes['answervalue'], ".") !== false) { // Remove last 0 and last . ALWAYS (see \SurveyObj\getShortAnswer)
$aQuestionAttributes['answervalue'] = rtrim(rtrim($aQuestionAttributes['answervalue'], "0"), ".");
}
Expand Down

5 comments on commit 2eb78e6

@Shnoulle
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For develop : move this to schema ? https://github.com/LimeSurvey/LimeSurvey/tree/master/application/core/db
Unsure Yii have a solution for getAttribute …

@olleharstedt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would that work?

@Shnoulle
Copy link
Collaborator Author

@Shnoulle Shnoulle commented on 2eb78e6 Jan 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean : here we have X times the same system for DECIMAL value

  1. Test if start by dot : if yes : add 0
  2. Remove the last 0 and the last dot (if it's X.0000000)

I like to move all to a singlle function, related to DB …

BUT : don't find the good place to extend CActiveRecord->getAttribute ? Unsure is the best …

Use onAfterFind in Response ans SurveyDynamic ?

@olleharstedt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best if it only affects the MSSQL abstraction layer.

@Shnoulle
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MSSQL for .000000 and Mysql (maybe pgsql) for 0.00000000

BUT : yii have abstraction layer for request condtruction, but not for result … result are … result done by DB , except of i made error ?

Please sign in to comment.