I use Cassandra-PHP-Client-Library library for get/set data to Apache Cassandra.
I created a keyspace name via cqlsh coomanda line:
CREATE TABLE employees (
company text,
name text,
age int,
role text,
PRIMARY KEY (company,name)
);
Then have inserted some columns also via command line:
INSERT INTO employees (company, name, age, role) VALUES ('OSC', 'eric', 38, 'ceo');
INSERT INTO employees (company, name, age, role) VALUES ('OSC', 'john', 37, 'dev');
Now I try insert any data from php, for this i use method set() of library:
$this->cassandra->set(
'employees.company',
array(
'company' => 'alicerozenberg#gmail.com',
'name' => 'Alice Rozenberg',
'age' => 45,
'role' => 'ddd'
)
);
In the official manual was told that first param of function set() is key row (employees is a name of column family, company is a key), and other - are name and value of columns.
In this regard, I have a few questions:
What is a row key in my case? At the "CREATE" command I specifed, that primary key is "company,name". But this not correct for use in function. This option does not work:
$this->cassandra->set(
'employees.name',
...
$this->cassandra->set(
'employees.company',
...
I change to phpcassa library and have question about composites types:
From tutorial example:
https://github.com/thobbs/phpcassa/blob/master/examples/composites.php
// Insert a few records
$key1 = array("key", 1);
$key2 = array("key", 2);
$columns = array(
array(array(0, "a"), "val0a"),
array(array(1, "a"), "val1a"),
array(array(1, "b"), "val1b"),
array(array(1, "c"), "val1c"),
array(array(2, "a"), "val2a"),
array(array(3, "a"), "val3a")
);
Who can me tell, what composire array will be in my case for two row keys "name, company"? Thank you!
PRIMARY KEY (company,name)
Compound primary keys in Cassandra have multiple parts. The first column (company in your case) is your partitioning key. This is the key that will help determine which partition the row is stored on.
The next part of a compound primary key, are the clustering columns. The clustering columns indicate the on-disk sort order of your data. In your case, you only have one clustering column (name). Your row data will then be stored by a (assumed unique) combination of company and name, and your data will be sorted (on-disk) by name.
What is a row key in my case?
The row key in your case is this combination of both company and name.
Now how do you set that in your PHP (PHPCassa?) code? I'm not exactly sure. But from what I'm reading on this blog posting (warning: it is a couple of years old) titled Cassandra PHPCassa & Composite Types, you may need to define your rowkey as an array, like this:
$this->cassandra->set(
array('employees.company','employees.name'),
array(
'age' => 45,
'role' => 'ddd'
)
);
Try that and see if it helps. Otherwise, reference the article I linked above.
Based on your most-recent edit, I think your key definition will look something like this:
$key = array("alicerozenberg#gmail.com", "Alice Rozenberg");
$columns = array(45,"ddd");
$cf->insert($key, $columns);
Related
My data looks like:
countyFIPS,County Name,State,stateFIPS,1/22/20,1/23/20,1/24/20,1/25/20,....
1001,Autauga County,AL,1,0,0,0,0,0,0,0,0,....
...
I've been able to retrieve it using an Ajax call and collect it into a simple PHP array, then convert it to json to use in my javascript application. While it appears that the data is all counties of a state, followed by the same configuration for the next state, there is no guarantee that it won't be mixed up in some later set of data.
I'm an old Fortran programmer, and would tend to build a hash table for the "states", then check if the state exists in the hash table. If not create a new hash table and add this empty hash table as the value for the key with the name of the state to the "state" hash table. Then check the state hash table to see if it has a key for the county. Again, if it doesn't, then add an empty array as the value for the key with the county name and add that to the state hash table, then proceed to put the values for that row into the county array. I know this will work, but thought maybe there was some clever way to use associative arrays in PHP to accomplish the same thing.
I look at array_filter, but can't seem to figure out how to adapt it to this case. Are there other functions that might work here?
Then, once I have this structure of
$nested_object = { state1=>{county1,county2,county3...},state2=>{counties}},
and those counties have:
county=>[values],
how can I easily convert this to a json structure? Should it have other keys like "states", and within a state "counties". From looking at Haroldo's question "Convert a PHP object to an associative array" of Dec 3, 2010, it appears like I would use:
$array = json_decode(json_encode($nested_object), true);
Will this give me the structure I am looking for?
I want to end up with a structure that I can ask for the states as a set of keys, then for a selected state ask for the counties in that state as a set of keys, and upon selecting one, get the array of values for that state/county. This has to run on a server with potentially a large amount of data and a moderate amount of hits per unit time so I wanted as reasonably efficient way as possible.
I want to end up with a structure that I can ask for the states as a set of keys, then for a selected state ask for the counties in that state as a set of keys, and upon selecting one, get the array of values for that state/county
Okay, so you need something like:
$structure = [
'AL' => [
'counties' => [
'FIPS1' => 'County1',
'FIPS2' => 'County2',
],
'data' => [
'FIPS1' => [
[ 'date1' => value1, 'date2' => value2, 'date3' => value3... ]
],
],
],
'AK' => [ ... ]
];
You can do that using array_map() and a lambda function writing to $structure, but... in my experience, it is not worth it.
Best to do like you said:
while ($row = get_another_row()) {
$countyFIPS = array_unshift($row);
$countyName = array_unshift($row);
$stateName = array_unshift($row);
$stateFIPS = array_unshift($row);
if (!array_key_exists($stateName, $structure)) {
$structure[$stateName] = [
'counties' => [ ],
'data' => [ ],
];
}
if (!array_key_exists($countyFIPS, $structure[$stateName]['counties'])) {
$structure[$stateName]['counties'][$countyFIPS] = $countyName;
$structure[$stateName]['data'][$countyFIPS] = [ ];
}
// Now here you will have $headers, obtained from the header row unshifting
// the first four fields.
foreach ($headers as $i => $key) {
$structure[$stateName]['data'][$countyFIPS][$key] = $row[$i];
}
}
This way if you add two CSVs with different dates, the code will still work properly. Dates will not be sorted though, but you can do that with a nested array_map and the aksort function.
To output this in JSON, just use json_encode on $structure.
I have a dropdown on my site that allows for multiple selections:
$this->Form->input('systems', array('label'=>'System Assignments', 'empty'=>'', 'default'=>'', 'div'=>false, 'multiple'=>true, 'class'=>'chosen',
'options'=>$systems));
This code from my controller populates the $systems variable:
$systems = $this->Discrepancy->find('list', array('fields' => array('id', 'description'),
'conditions'=>array('Discrepancy.deleted_record' => 0),
'order'=>array('Discrepancy.display_order'=>'ASC')));
$this->set(compact('systems'));
When the user makes their selection(s), the row ID's are stored as an array in a table called Users in a field called systems.
$system_string = implode(',', $this->request->data['User']['systems']);
$this->request->data['User']['systems'] = $system_string;
systems
-------
50,22
On my Edit screen, I would like to be able to use that array of values as my list of ID's for retrieving and displaying the user's system choices, by adding a 'value' parameter to the dropdown.
'value'=>array_key($chosen_systems);
How can I use these stored values in a $this->Model->find statement?
Got it. Guess I needed to write it all out first.
Put the following line in the $this->Model->find statement:
'conditions'=>array('Discrepancy.id'=>explode(',',$var_for_systems_from_db))
i have a code like this ,
$request = Yii::$app->request;
$post = $request->post();
$filesettingid = $post['filesettingid'];
$checkboxValue = $post['selection'];
for($i=0;$i<sizeof($checkboxValue);$i++) {
$store = Yii::$app->db->createCommand('SELECT id FROM store WHERE port='.$checkboxValue[$i])->queryAll();
$storeid = $store[$i]['id'];
Yii::$app->db->createCommand()->insert('tes',
[
'id' => $i+1,
'filesetting_id' => $filesettingid,
'store_id' => $storeid
])->execute();
}
what i want is, each i insert the new data, id will generate automaticly like 1,2,3,4.
the problem in above code is, the ID always be 1.
is it possible to make it real?
so what i want is :
First time insert, id = 1, second is id = 2 , and that is happen automatically.
Have you considered setting database engine to auto increment values with each insert?
Take as an example Yii2 default user table. ID filed is auto incremented, and you don't have to worry about setting it problematically. Every time you send a new insert engine increments ID filed by itself.
See default migration under "advanced template"\console\migrations\m130524_201442_int. (your file name might be different depending on the Yii2 version)
$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string()->notNull()->unique(),
'auth_key' => $this->string(32)->notNull(),
'password_hash' => $this->string()->notNull(),
'password_reset_token' => $this->string()->unique(),
'email' => $this->string()->notNull()->unique(),
'status' => $this->smallInteger()->notNull()->defaultValue(0),
.........
], $tableOptions);
When setting 'id' to primary key database automatically knows to auto increment it. If you already have a table the ID field is not primary key you can use the followign migration:
$this->alterColumn('{{%databaseName}}', 'columnName', $this->integer()->notNull().' AUTO_INCREMENT');
You can also set it from management console, or run a SQL query. Depending on database engine you are using this might look a little different but the concept is the same.
MYSQL:
In MySQL workbench right click on table in question, select Alter Table and check NNm and AI next to column you want auto increment. See Screenshot
Or run command:
ALTER TABLE `dbName`.`nameOfTheTable` MODIFY `columnName` INT AUTO_INCREMENT NOT NULL;
I am a bit rusty on my SQL, so if it does not work let me know I will get you right command.
Hope this helps. Good luck.
I want to update database in CAKEPHP's Way
this is my controller
$data = array(
'KnowledgeBase' => array(
'kb_title' => $this->data['KnowledgeBase']['kb_title'],
'kb_content' => $this->data['KnowledgeBase']['kb_content']
'kb_last_update' => date("Y-m-d G:i:s"),
'kb_segment' => $this->data['KnowledgeBase']['kb_segment']
));
$this->KnowledgeBase->id_kb = $this->data['KnowledgeBase']['id_kb'];
$this->KnowledgeBase->save($data);
assume I have post form is true, when I execute the program
I have some error like this :
Database Error
Error: SQLSTATE[23000]: [Microsoft][SQL Server Native Client 10.0]
[SQL Server]Violation of PRIMARY KEY constraint 'PK_cnaf_kb'.
Cannot insert duplicate key in object 'dbo.cnaf_kb'.
SQL Query: INSERT INTO [cnaf_kb] ([kb_judul], [kb_segment], [kb_isi], [id_kb], [kb_last_update], [kb_status]) VALUES (N'HARRIS TEST 4 ', N'4', N'<p>TESSSSSSSSSSSSSSSSSSSSSS</p> ', 73,
'2013-10-04 16:57:00', 1)
why the function use the insert query? not update ?
note : im not using form helper for post to controller, and I use Cakephp 2.3.8 version and sql server 2008 for database
Im sorry for my bad english, I hope someone can help me :(((
You do not supply a primary key value, that's why.
No matter what your primary key is named (Model::$primaryKey), on the model object you have to use the id property (Model::$id) if you want to set the primary key value.
$this->KnowledgeBase->id = $this->data['KnowledgeBase']['id_kb'];
Internally the model maps this to the appropriate primary key field.
In the data however you'd use the actual primary key name:
'id_kb' => $this->data['KnowledgeBase']['id_kb']
btw, I'm not sure why you are (re)building the data array, but if it's to make sure that only specific fields are saved, then you could use the fieldList option instead:
$this->data['KnowledgeBase']['kb_last_update'] = date('Y-m-d G:i:s');
$options = array(
'fieldList' => array(
'kb_title',
'kb_content',
'kb_last_update',
'kb_segment'
)
);
$this->KnowledgeBase->save($this->data, $options);
I have the following mysql db row.
id | user_id | title_1|desc_1|link_1|title_2|desc_2|link_2|
and so on up to 10
from this one row I want to remove id and user id and have the resulting multidimensional array.
the main issue is iterarating over the associative array that is returned by my query and splitting it up into arrays of 3.
Array = (
[0] = array (
[tite_1] => 'sometitle'
[desc_1] => 'description'
[link_1] => 'a link'
)
[1] = array (
[tite_2] => 'sometitle'
[desc_2] => 'description'
[link_2] => 'a link'
)
and so on how can I achieve this I am stumped!!?
You probably want to structure your table into two tables like this:
parent(id, user_id, more_fields, whatever_you_need_here)
child(parent_id, title, desc, link)
Now it'll be very easy to get the data that you want to have.
SELECT title, desc, link FROM child WHERE parent_id = 12;
Of course, parent and child should be named appropriately, e.g. user and links.
The correct answer would be to redesign your database to use 3rd normal form. You should probably drop everything and read up on database normalization before you do anything further.
A proper design would be something like:
CREATE TABLE user_has_links (
id INT PRIMARY KEY,
user_id INT,
title TEXT,
description TEXT,
link TEXT
)
To store multiple links per user, you would simply create a new row in this table per link.
The real solution here is to fix your database to normalize these columns into other tables. However, if you are not in a position to fix your database, this code will do the job:
// $output will hold your full result set
$output = array();
while ($row = mysql_fetch_assoc($result)) {
// For each row returned, add a new array to $output
$output[] = array(
// The new array consists of 10 sub-arrays with the correct
// keys and values
array (
"title"=>$row['title1'],
"desc"=>$row['desc1'],
"link"=>$row['link1']
),
array (
"title"=>$row['title2'],
"desc"=>$row['desc2'],
"link"=>$row['link2']
),
...,
...,
array (
"title"=>$row['title10'],
"desc"=>$row['desc10'],
"link"=>$row['link10']
)
);
}