Error on room database migration test, due to a wrong "primaryKeyPosition" value - database-migration

I am testing a room migration and on the "migration and validation" step I got an java.lang.IllegalStateException: Migration failed. due to a wrong primaryKeyPosition value on the "service_id" column. Digging a little bit deeper I noticed that on the Expected side the attributes in the actual_visit_id_service_id_primary_key have different pk indexes (1, 2), while on the Found side, both have the same (1, 1)
I checked into the database schema of table actual_visit_service in the installed app and the pk for the column service_id is 2 (like expected)
The failing entity:
#Entity(
tableName = ACTUAL_VISIT_SERVICE_TABLE,
indices = [Index(
value = [ACTUAL_VISIT_SERVICE_SERVICE_ID, ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID], unique = true
)],
foreignKeys = [(ForeignKey(
entity = ActualVisitEntity::class,
parentColumns = [ID],
childColumns = [ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID],
onDelete = ForeignKey.CASCADE
))],
primaryKeys = [ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID, ACTUAL_VISIT_SERVICE_SERVICE_ID]
)
data class ActualVisitServicesEntity(
#ColumnInfo(name = ACTUAL_VISIT_SERVICE_ACTUAL_VISIT_ID)
val actualVisitId: String,
#ColumnInfo(name = ACTUAL_VISIT_SERVICE_AMOUNT)
val amount: Double?,
#ColumnInfo(name = ACTUAL_VISIT_SERVICE_DURATION)
val duration: Int?,
#ColumnInfo(name = IS_SYNCHRONIZED)
var isSynchronized: Boolean = false,
#ColumnInfo(name = ACTUAL_VISIT_SERVICE_HAS_BEEN_PROVIDED)
var hasBeenProvided: Boolean,
#ColumnInfo(name = ACTUAL_VISIT_SERVICE_REJECTION_CATEGORY)
var rejectionCategory: String?,
#ColumnInfo(name = ACTUAL_VISIT_SERVICE_REJECTION_REASON)
var rejectionReason: String?,
#ColumnInfo(name = ACTUAL_VISIT_SERVICE_SERVICE_ID)
val serviceId: String
) : BaseEntity() {
....
}
The migration:
#JvmField
val MIGRATION_18_TO_19 = object : Migration(18, 19) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE planned_visit ADD COLUMN hint TEXT")
}
}
The error I got:
java.lang.IllegalStateException: Migration failed.
Expected:TableInfo{name='actual_visit_services', columns={duration=Column{name='duration', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}, amount=Column{name='amount', type='REAL', affinity='4', notNull=false, primaryKeyPosition=0}, actual_visit_id=Column{name='actual_visit_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, rejection_category=Column{name='rejection_category', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, has_been_provided=Column{name='has_been_provided', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, service_id=Column{name='service_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=2}, rejection_reason=Column{name='rejection_reason', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, is_synchronized=Column{name='is_synchronized', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}}, foreignKeys=[ForeignKey{referenceTable='actual_visits', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[actual_visit_id], referenceColumnNames=[id]}], indices=[Index{name='index_actual_visit_services_service_id_actual_visit_id', unique=true, columns=[service_id, actual_visit_id]}]}
found:TableInfo{name='actual_visit_services', columns={duration=Column{name='duration', type='INTEGER', affinity='3', notNull=false, primaryKeyPosition=0}, amount=Column{name='amount', type='REAL', affinity='4', notNull=false, primaryKeyPosition=0}, actual_visit_id=Column{name='actual_visit_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, rejection_category=Column{name='rejection_category', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, has_been_provided=Column{name='has_been_provided', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}, service_id=Column{name='service_id', type='TEXT', affinity='2', notNull=true, primaryKeyPosition=1}, rejection_reason=Column{name='rejection_reason', type='TEXT', affinity='2', notNull=false, primaryKeyPosition=0}, is_synchronized=Column{name='is_synchronized', type='INTEGER', affinity='3', notNull=true, primaryKeyPosition=0}}, foreignKeys=[ForeignKey{referenceTable='actual_visits', onDelete='CASCADE', onUpdate='NO ACTION', columnNames=[actual_visit_id], referenceColumnNames=[id]}], indices=null}
As you see on "Expected" you have:
service_id=Column{name= ... primaryKeyPosition=2}
but on "Found":
service_id=Column{name= ... primaryKeyPosition=1}
I use Room from the beginning but I just started with the migrations, being the previous database build version 18 and the new one 19. I run the regular entities and DAOs test with Robolectric and I intend to do the same with the migration tests.
Why do the two attributes in the composed primary key have the same pk index in the migrated database?

Related

Amcharts 4: On hover bar in ColumnSeries change color

I have a ColumnSeries chart that looks like this:
When I hover a bar I want it to change color to #ffe876.
I have tried to add a hoverState but it doesnt work:
// Create a hover state
var hoverState = valueAxis.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
This is my code:
<script>
am4core.ready(function() {
var chart = am4core.create("chartdiv_visits_per_week", am4charts.XYChart);
chart.data = [
{
"x": "31",
"value": 1
},
{
"x": "32",
"value": 2
},
{
"x": "33",
"value": 2
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "x";
categoryAxis.renderer.grid.template.disabled = true;
categoryAxis.renderer.labels.template.disabled = true;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.grid.template.disabled = true;
valueAxis.renderer.labels.template.disabled = true;
// Create series
var series1 = chart.series.push(new am4charts.ColumnSeries);
series1.dataFields.valueY = "value";
series1.dataFields.categoryX = "x";
series1.name = "Human unique";
series1.tooltipText = "Human unique week {categoryX}: {valueY}";
series1.fill = am4core.color("#f2a654");
series1.stroke = am4core.color("#f4b570");
series1.strokeWidth = 0;
// Tooltips
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series;
chart.cursor.xAxis = valueAxis;
}); // end am4core.ready()
</script>
<div id="chartdiv_visits_per_week" style="height: 100px;"></div>
What can I do to make the bar change color when I hover it?
You need to add the state to the series, not the axis.
var hoverState = series1.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
Demo below:
var chart = am4core.create("chartdiv_visits_per_week", am4charts.XYChart);
chart.data = [
{
"x": "31",
"value": 1
},
{
"x": "32",
"value": 2
},
{
"x": "33",
"value": 2
}
];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "x";
categoryAxis.renderer.grid.template.disabled = true;
categoryAxis.renderer.labels.template.disabled = true;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.grid.template.disabled = true;
valueAxis.renderer.labels.template.disabled = true;
// Create series
var series1 = chart.series.push(new am4charts.ColumnSeries);
series1.dataFields.valueY = "value";
series1.dataFields.categoryX = "x";
series1.name = "Human unique";
series1.tooltipText = "Human unique week {categoryX}: {valueY}";
series1.fill = am4core.color("#f2a654");
series1.stroke = am4core.color("#f4b570");
series1.strokeWidth = 0;
// Create a hover state
var hoverState = series1.columns.template.states.create("hover");
hoverState.properties.fill = am4core.color("#ffe876");
// Tooltips
chart.cursor = new am4charts.XYCursor();
chart.cursor.snapToSeries = series1;
chart.cursor.xAxis = valueAxis;
<script src="//cdn.amcharts.com/lib/4/core.js"></script>
<script src="//cdn.amcharts.com/lib/4/charts.js"></script>
<script src="//cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv_visits_per_week" style="height: 100px;"></div>

I implemented a star rating system for delivery man in django by users but i am stuck at how to calculate the average

I have a model name Ratings and its connected to custom user model through foreignkey relationship.i used javascript to post data and get ratings in the backend by get method using id but the problem is rating process works fine but it just upgrades the current queryset when ever regarded delivery man gets rated. so how do i calculatye the average as it does not store the previous querysets rather its just upgrades the queryset of that particular deliveryman
views.py
def rate_user(request):
if request.method == 'POST':
el_id = request.POST.get('el_id')
val = request.POST.get('val')
print(val)
obj = Ratings.objects.get(id=el_id)
obj.rated_number = val
obj.save()
return JsonResponse({'success':'true', 'score': val}, safe=False)
return JsonResponse({'success':'false'})
models.py
class Ratings(models.Model):
rated_user = models.ForeignKey(User,on_delete=models.CASCADE,blank=True,null=True)
avg_rating = models.CharField(max_length=5,null=True,blank=True,default=0)
# count = models.CharField(max_length=100000,blank=True,null=True,default=0)
rated_number = models.IntegerField(blank=True,null=True,default=0,
validators = [
MaxValueValidator(5),
MinValueValidator(1),
]
)
def __str__(self):
return str(self.pk)
#receiver(post_save, sender=User)
def create_ratings(sender, instance, created, **kwargs):
if created:
if instance.is_delivery_man or instance.is_driver:
Ratings.objects.create(rated_user=instance)
js
<script>
const one = document.getElementById('first')
const two = document.getElementById('second')
const three = document.getElementById('third')
const four = document.getElementById('fourth')
const five = document.getElementById('fifth')
// get the form, confirm-box and csrf token
const form = document.querySelector('.rate-form')
const confirmBox = document.getElementById('confirm-box')
const csrf = document.getElementsByName('csrfmiddlewaretoken')
const handleStarSelect = (size) => {
const children = form.children
console.log(children[0])
for (let i = 0; i < children.length; i++) {
if (i <= size) {
children[i].classList.add('checked')
} else {
children[i].classList.remove('checked')
}
}
}
const handleSelect = (selection) => {
switch (selection) {
case 'first': {
handleStarSelect(1)
return
}
case 'second': {
handleStarSelect(2)
return
}
case 'third': {
handleStarSelect(3)
return
}
case 'fourth': {
handleStarSelect(4)
return
}
case 'fifth': {
handleStarSelect(5)
return
}
default: {
handleStarSelect(0)
}
}
}
const getNumericValue = (stringValue) => {
let numericValue;
if (stringValue === 'first') {
numericValue = 1
}
else if (stringValue === 'second') {
numericValue = 2
}
else if (stringValue === 'third') {
numericValue = 3
}
else if (stringValue === 'fourth') {
numericValue = 4
}
else if (stringValue === 'fifth') {
numericValue = 5
}
else {
numericValue = 0
}
return numericValue
}
if (one) {
const arr = [one, two, three, four, five]
arr.forEach(item => item.addEventListener('mouseover', (event) => {
handleSelect(event.target.id)
}))
arr.forEach(item => item.addEventListener('click', (event) => {
// value of the rating not numeric
const val = event.target.id
let isSubmit = false
form.addEventListener('submit', e => {
e.preventDefault()
if (isSubmit) {
return
}
isSubmit = true
// rate id
const id = e.target.id
// value of the rating translated into numeric
const val_num = getNumericValue(val)
$.ajax({
type: 'POST',
url: '/rate/',
data: {
'csrfmiddlewaretoken': csrf[0].value,
'el_id': id,
'val': val_num,
},
success: function (response) {
console.log(response)
confirmBox.innerHTML = `<h1>Successfully rated with ${response.score} star</h1>`
},
error: function (error) {
console.log(error)
confirmBox.innerHTML = '<h1>Ups... something went wrong</h1>'
}
})
})
}))
}
</script>
Form
{%for i in ratings%}
<a href="#" >Average Ratings: {{i.rated_number}}</a><br><br>
i class="fas fa-vote-yea"></i> Rate this user <br>
<form class="rate-form" action="" method="POST" id={{i.id}}>
{% csrf_token %}
<button type="submit" class="fa fa-star fa-3x my-btn" id="first"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="second"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="third"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="fourth"></button>
<button type="submit" class="fa fa-star fa-3x my-btn" id="fifth"></button>
</form>
{%endfor%}
<br>
<div id="confirm-box"></div>
</div>
Finally waiting for answer from stackoverflow i got tired and started debugging myself and i ended up with an nice mathmetical algorithm to achieve my desired goal and i think i have achieved it except it doest show or take values after decimal. avg are coming with a round shape .
i just changed a field in my model to store previous and now all rating number addition
class Ratings(models.Model):
rated_user = models.ForeignKey(User,on_delete=models.CASCADE,blank=True,null=True)
storing_prev_now_rated_value = models.IntegerField(null=True,blank=True,default=1)
avg_rating = models.IntegerField(null=True,blank=True,default=1)
count = models.IntegerField(blank=True,null=True)
rated_number = models.IntegerField(blank=True,null=True,default=1,
validators = [
MaxValueValidator(5),
MinValueValidator(1),
]
)
def __str__(self):
return self.rated_user.username
and i have changes in my views.py too
def rate_user(request):
if request.method == 'POST':
el_id = request.POST.get('el_id')
val = request.POST.get('val')
print(val)
obj = Ratings.objects.get(id=el_id)
storing_prev_rated_number = obj.rated_number
obj.rated_number = val
obj.count = obj.count + 1
store_count = obj.count
old_addition_values = obj.storing_prev_now_rated_value
obj.storing_prev_now_rated_value = int(old_addition_values) + int(val)
store_storing_prev_now_rated_value = obj.storing_prev_now_rated_value
print(store_storing_prev_now_rated_value)
obj.avg_rating = float(store_storing_prev_now_rated_value // store_count)
j = obj.avg_rating
print(j)
obj.save()
return JsonResponse({'success':'true', 'rated_number': val}, safe=False)
return JsonResponse({'success':'false'})

Calling Web Service method throwing Remote Disconnected error in Zeep

I am using the Python Zeep library to call Maximo web services and able to fetch the WSDL without any issues. When I am trying to query using one of the method in Web service, it is throwing error
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response',))
multiasset_wsdl = "http://maximoqa.xyz.com:9080/meaweb/services/MULTIASSET?wsdl"
work_order = 'NA0000211'
# set the session
session = Session()
session.auth = HTTPBasicAuth(Username, Password)
session.verify = False
transport = Transport(session=session)
settings = Settings(strict=False ,force_https = False)
maximo_multiasset_client = Client(multiasset_wsdl, transport=transport, settings=settings
multiasset_type_factory = maximo_multiasset_client.type_factory('ns0')
mult_asset_query = multiasset_type_factory.QueryMULTIASSETType(
baseLanguage = "?",
creationDateTime = tt.get_now(),
maximoVersion = "?",
maxItems = "1",
messageID = "?",
rsStart = "0",
transLanguage = "EN",
uniqueResult = False,
MULTIASSETQuery = multiasset_type_factory.MULTIASSETQueryType
(
operandMode = multiasset_type_factory.OperandModeType('AND'),
orderby = "?",
WHERE = f"WONUM='{work_order}'",
WORKORDER = None
)
)
print('Calling Query MultiAsset')
query_response = maximo_multiasset_client.service.QueryMULTIASSET(mult_asset_query)
Appreciate any help on this issue.

selectInput Category selection

I have a selectInput code as like this
selectInput('x4', 'X4', choices = list(
Eastern = c(`New York` = 'NY', `New Jersey` = 'NJ'),
Western = c(`California` = 'CA', `Washington` = 'WA')
), selectize = FALSE)
Is it possible enable section on category, like Eastern, Western. If user selected Eastern both values have to load ( New Jersey and New York). Is it possible ?
library(shiny)
onInitialize <- "
function(){
var select = this.$input[0];
this.$dropdown_content.on('mousedown', function(e){
e.preventDefault();
return false;
}).on('click', '.optgroup-header', function(e){
var options = $(this).parent().find('.option');
var items = [];
options.each(function(i, opt){items.push($(opt).data('value'));});
var selections = select.selectize.items;
select.selectize.setValue(items.concat(selections));
});
}
"
shinyApp(
ui = fluidPage(
selectizeInput("state", "Choose a state:",
list(`East Coast` = list("NY", "NJ", "CT"),
`West Coast` = list("WA", "OR", "CA"),
`Midwest` = list("MN", "WI", "IA")),
multiple = TRUE,
options = list(
onInitialize = I(onInitialize)
)
)
),
server = function(input, output){}
)

How to log WS Security username and SOAP method on Mule

I have an application that will validate username and password to give access to a soap webservice and im trying to log the username and method used, so how to log that info into a database (get user and method)?
this is the code i have so far:
<mule-ss:security-manager
xmlns:mule-ss="http://www.mulesoft.org/schema/mule/spring-security">
<mule-ss:delegate-security-provider
name="jdbc-provider" delegate-ref="authenticationManager" />
</mule-ss:security-manager>
<spring:beans>
<spring:bean id="loggingInInterceptor"
class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<spring:bean id="loggingOutInterceptor"
class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<spring:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<spring:property name="driverClassName" value="org.postgresql.Driver" />
<spring:property name="url" value="jdbc:postgresql://127.0.0.1/anydb" />
<spring:property name="username" value="anyuser" />
<spring:property name="password" value="0123456" />
</spring:bean>
<ss:http xmlns:ss="http://www.springframework.org/schema/security"
auto-config="true" use-expressions="true" request-matcher="regex">
<ss:intercept-url pattern="^/services/any/anyservice"
access="hasRole('ROLE_ANY')" />
</ss:http>
<ss:authentication-manager
xmlns:ss="http://www.springframework.org/schema/security" alias="authenticationManager">
<ss:authentication-provider>
<ss:jdbc-user-service data-source-ref="dataSource"
users-by-username-query="
select username, password, enabled
from users where username=?"
authorities-by-username-query="
select u.username, ur.authority from users u, authorities ur
where u.id = ur.user_id and u.username =? " />
</ss:authentication-provider>
</ss:authentication-manager>
</spring:beans>
<jdbc:postgresql-data-source name="postgreName"
user="anyuser" password="0123456" url="jdbc:postgresql://127.0.0.1/anyservice"
transactionIsolation="UNSPECIFIED" doc:name="PostgreSQL Data Source">
</jdbc:postgresql-data-source>
<jdbc:connector name="jdbcConnector" dataSource-ref="postgreName"
validateConnections="false" queryTimeout="10" pollingFrequency="10000"
doc:name="Database">
<reconnect frequency="3000" blocking="false" />
<jdbc:query key="anydb" value="insert into inbound_msgs (ip_from, request_size, modified_request_size, timestamp, url)
values (
#[groovy: return message.getInboundProperty('MULE_REMOTE_CLIENT_ADDRESS').toString()],
#[groovy: return message.getInboundProperty('http.request.old').toString().length()],
#[groovy: return message.getInboundProperty('http.request').toString().length()],
now(),
#[groovy: return message.getInboundProperty('http.context.uri').toString()]);">
</jdbc:query>
</jdbc:connector>
<scripting:transformer name="noopLoggingTransformer"
doc:name="Script">
<scripting:script engine="groovy">
def props = [:]
//props['User-Agent'] = message.getProperty('User-Agent', org.mule.api.transport.PropertyScope.INBOUND)
props['MULE_REMOTE_CLIENT_ADDRESS'] =
message.getProperty('MULE_REMOTE_CLIENT_ADDRESS',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.context.uri'] = message.getProperty('http.context.uri',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request.old'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
muleContext.client.dispatch('vm://log-request.in', payload, props)
message
</scripting:script>
</scripting:transformer>
<flow name="log-request" doc:name="log-request">
<vm:inbound-endpoint path="log-request.in"
doc:name="VM" />
<jdbc:outbound-endpoint exchange-pattern="one-way"
queryKey="anydb" responseTimeout="10000" queryTimeout="10"
connector-ref="jdbcConnector" doc:name="Persist raw message">
</jdbc:outbound-endpoint>
</flow>
<pattern:web-service-proxy name="logBypass" doc:name="logBypass">
<inbound-endpoint address="http://localhost/services/logBypass" exchange-pattern="request-response" transformer-refs="noopLoggingTransformer">
<mule-ss:http-security-filter realm="mule-realm"></mule-ss:http-security-filter>
</inbound-endpoint>
<outbound-endpoint address="http://targetServer/logBypass" exchange-pattern="request-response"/>
</pattern:web-service-proxy>
Mule version 3.4.0
After a few days i came with a solution to my problem:
with:
<scripting:transformer name="noopLoggingTransformer"
doc:name="Script">
<scripting:script engine="groovy">
import org.apache.commons.codec.binary.Base64
def props = [:]
//props['User-Agent'] = message.getProperty('User-Agent', org.mule.api.transport.PropertyScope.INBOUND)
props['MULE_REMOTE_CLIENT_ADDRESS'] =
message.getProperty('MULE_REMOTE_CLIENT_ADDRESS',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.context.uri'] = message.getProperty('http.context.uri',
org.mule.api.transport.PropertyScope.INBOUND)
props['http.request.old'] = message.getProperty('http.request',
org.mule.api.transport.PropertyScope.INBOUND)
def headerData = message.getProperty('http.headers',org.mule.api.transport.PropertyScope.INBOUND)
def userName = ""
if (headerData["Authorization"] != null) {
def security = headerData["Authorization"].split(" ")
def bytes = security[1].bytes
Base64 coder = new Base64()
def decodedData = coder.decode(bytes)
def userNamePwd = new String(decodedData)
def userNameSplit = userNamePwd.split(":")
userName = userNameSplit[0]
}
props['userName'] = userName
def method = ""
if (headerData["SOAPAction"] != null) {
method = headerData["SOAPAction"]
}
props['method'] = method
muleContext.client.dispatch('vm://log-request.in', payload, props)
message
</scripting:script>
</scripting:transformer>
That and the code from the question will work perfect on Mule 3.4.0
Remember to change the database to adapt to your necessity.